You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
3.6 KiB
141 lines
3.6 KiB
<template> |
|
<Tooltip :infos="[t('archive.0')]" width="12rem"> |
|
<img class="menu-img" :src="menu_icons.exportGame" @click="showMenu"> |
|
</Tooltip> |
|
|
|
<Dialog :title="t('archive.0')" v-model="showArchive" top="15%" left='8%'> |
|
<div class="archive"> |
|
<span class="tip">* {{ t('archive.1') }}</span> |
|
<textarea class="textarea" v-model="archive"></textarea> |
|
</div> |
|
<div class="footer"> |
|
<button class="button" @click="copyArchive">{{ t('copyArchive.0') }}</button> |
|
<button class="button" @click="pasteArchive">{{ t('pasteArchive.0') }}</button> |
|
<button class="button" @click="importArchive">{{ t('importArchive.0') }}</button> |
|
</div> |
|
</Dialog> |
|
|
|
</template> |
|
|
|
<script lang="ts" setup> |
|
import { useStore } from "vuex"; |
|
import { computed, onMounted, ref, onBeforeUnmount } from "vue"; |
|
import { useI18n } from "vue3-i18n"; |
|
import { Tooltip, Dialog } from "@/components" |
|
import { menu_icons } from "@/config"; |
|
import { getArchive, AES_CBC_ENCRYPT, AES_CBC_DECRYPT, checkImportArchive, saveArchive } from "@/tool"; |
|
|
|
|
|
const { t } = useI18n(); |
|
const { state, commit, dispatch } = useStore(); |
|
const showArchive = computed(() => { |
|
return state.curMenu == 'archive'; |
|
}); |
|
const archive = ref(''); |
|
const key = 'KUf4hM5rThssysJhcRFCfxLR8Imihjl0eMsyhh1M7Wk'; |
|
|
|
const showMenu = () => { |
|
if (showArchive.value) { |
|
state.curMenu = null; |
|
} else { |
|
state.curMenu = 'archive'; |
|
getArchive().then((rsp: any) => { |
|
archive.value = AES_CBC_ENCRYPT(JSON.stringify(rsp), key); |
|
}); |
|
} |
|
} |
|
|
|
const copyArchive = () => { |
|
navigator.clipboard.writeText(archive.value).then(() => { |
|
commit('set_sys_info', { msg: t('copyArchive.1'), type: 'win' }) |
|
}, () => { |
|
commit('set_sys_info', { msg: t('copyArchive.2'), type: 'waring' }) |
|
}); |
|
showMenu(); |
|
} |
|
|
|
const pasteArchive = () => { |
|
navigator.clipboard.readText().then((text) => { |
|
archive.value = text; |
|
commit('set_sys_info', { msg: t('pasteArchive.1'), type: 'win' }) |
|
}, () => { |
|
commit('set_sys_info', { msg: t('pasteArchive.2'), type: 'waring' }) |
|
}); |
|
} |
|
|
|
const importArchive = async () => { |
|
try { |
|
const data = JSON.parse(AES_CBC_DECRYPT(archive.value, key)); |
|
if (!data || data == 'undfind') { |
|
commit('set_sys_info', { msg: t('loadEmpty'), type: 'warning' }); |
|
} |
|
await checkImportArchive(data); |
|
await dispatch('loadGame', data); |
|
saveArchive(state); |
|
showMenu(); |
|
} catch (error) { |
|
console.log(error); |
|
commit('set_sys_info', { msg: t('loadError'), type: 'warning' }); |
|
} |
|
} |
|
|
|
const keydown = (e) => { |
|
if (e.keyCode == 65 && !e.ctrlKey) { |
|
showMenu(); |
|
} |
|
} |
|
onMounted(() => { |
|
document.addEventListener('keydown', keydown) |
|
}); |
|
onBeforeUnmount(() => { |
|
document.removeEventListener('keydown', keydown) |
|
}) |
|
|
|
onMounted(() => { }); |
|
</script> |
|
<style lang="scss" scoped> |
|
.archive { |
|
padding: 0.7rem; |
|
display: flex; |
|
flex-direction: column; |
|
|
|
.tip { |
|
color: white; |
|
font-size: 0.8rem; |
|
margin: 0.25rem 0; |
|
} |
|
} |
|
|
|
.textarea { |
|
width: 25rem; |
|
height: 15rem; |
|
user-select: text; |
|
background: rgba($color: #ffffff, $alpha: 0.8); |
|
} |
|
|
|
.footer { |
|
border-top: 1px solid #ccc; |
|
padding: 0.4rem; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
|
|
@media only screen and (max-width: 768px) { |
|
.archive { |
|
padding: 0.3rem; |
|
|
|
.tip { |
|
color: white; |
|
font-size: 0.8rem; |
|
margin: 0.25rem 0; |
|
} |
|
} |
|
|
|
.textarea { |
|
width: 22rem; |
|
height: 20rem; |
|
} |
|
|
|
} |
|
</style> |