This commit is contained in:
johnathan 2025-06-09 15:06:29 +08:00
parent eee860f804
commit 74315474f8
10 changed files with 48 additions and 46 deletions

View File

@ -13,7 +13,7 @@ const openOptionsPage = async () => {
<stash:search-results />
</n-icon>
</template>
<template #default> 数据 </template>
<template #default>数据</template>
</n-button>
</div>
<n-space class="app-title">
@ -38,7 +38,7 @@ const openOptionsPage = async () => {
justify-content: flex-start;
.setting-button {
margin-right: 20px;
margin: 12px 20px 0 0;
opacity: 0.7;
&:hover {
opacity: 1;
@ -47,6 +47,6 @@ const openOptionsPage = async () => {
}
.app-title {
margin-top: 20px;
margin-top: 10px;
}
</style>

View File

@ -51,7 +51,7 @@ onUnmounted(() => {
trigger="hover"
placement="right"
:delay="1000"
:duration="1000"
:duration="500"
>
<template #trigger>
<span class="link-text">{{ url }}</span>

View File

@ -0,0 +1,4 @@
export const usePageContext = () => {
const pageContext = document.location.pathname.split('/')[2] as 'sidepanel' | 'options';
return { pageContext };
};

View File

@ -6,6 +6,7 @@ import { storage } from 'webextension-polyfill';
import type { RemovableRef, StorageLikeAsync, UseStorageAsyncOptions } from '@vueuse/core';
import type { Ref } from 'vue-demi';
import type { Storage } from 'webextension-polyfill';
import { usePageContext } from './usePageContext';
export type WebExtensionStorageOptions<T> = UseStorageAsyncOptions<T>;
@ -46,13 +47,6 @@ const storageInterface: StorageLikeAsync = {
},
};
/**
* Get page app context
*/
function getContext() {
return document.location.pathname.split('/')[2] as 'sidepanel' | 'options';
}
/**
* https://github.com/vueuse/vueuse/blob/658444bf9f8b96118dbd06eba411bb6639e24e88/packages/core/useStorageAsync/index.ts
*
@ -127,7 +121,7 @@ export function useWebExtensionStorage<T>(
return;
}
if (typeof listenToStorageChanges === 'string') {
const context = getContext();
const { pageContext: context } = usePageContext();
if (listenToStorageChanges !== context) {
return;
}

View File

@ -1,11 +1,12 @@
import type { App } from 'vue';
import { usePageContext } from '~/composables/usePageContext';
/**
* Setup Vue app
* @param app Vue app
*/
export function setupApp(app: App) {
const context = document.location.pathname.split('/')[2];
const { pageContext: context } = usePageContext();
// Inject a globally available `$app` object in template
app.config.globalProperties.$app = {

View File

@ -46,7 +46,7 @@ export async function exec<T, P extends Record<string, unknown>>(
const ret = injectResults.pop();
resolve(ret!.result as T);
} catch (e) {
throw new Error(`脚本运行失败: ${e}`);
throw new Error(`脚本运行失败: ${e}`);
}
});
}

View File

@ -17,6 +17,15 @@ const timelines = ref<
const { isRunning, startTask } = useLongTask();
const emit = defineEmits<{
start: [];
stop: [];
}>();
watch(isRunning, (newVal) => {
newVal ? emit('start') : emit('stop');
});
const asinInputRef = useTemplateRef('asin-input');
//#region Page Worker Code

View File

@ -4,6 +4,17 @@ import pageWorker from '~/logic/page-worker';
import type { AmazonReview } from '~/logic/page-worker/types';
import { reviewAsinInput, reviewItems } from '~/logic/storage';
const { isRunning, startTask } = useLongTask();
const emit = defineEmits<{
start: [];
stop: [];
}>();
watch(isRunning, (newVal) => {
newVal ? emit('start') : emit('stop');
});
const worker = pageWorker.useAmazonPageWorker();
worker.channel.on('error', ({ message: msg }) => {
timelines.value.push({
@ -24,8 +35,6 @@ worker.channel.on('item-review-collected', (ev) => {
updateReviews(ev);
});
const { isRunning, startTask } = useLongTask();
const asinInputRef = useTemplateRef('asin-input');
const message = useMessage();

View File

@ -8,6 +8,15 @@ import { useLongTask } from '~/composables/useLongTask';
const message = useMessage();
const { isRunning, startTask } = useLongTask();
const emit = defineEmits<{
start: [];
stop: [];
}>();
watch(isRunning, (newVal) => {
newVal ? emit('start') : emit('stop');
});
//#region Initial Page Worker
const worker = pageWorker.useAmazonPageWorker();
worker.channel.on('error', ({ message: msg }) => {

View File

@ -22,20 +22,22 @@ const currentComponent = computed(() => {
const tab = tabs.find((tab) => tab.name === selectedTab.value);
return tab ? tab.component : null;
});
const showHeader = ref(true);
const running = ref(false);
</script>
<template>
<div class="side-panel">
<div class="header-menu" v-if="showHeader">
<div class="header-menu">
<n-tabs
:tab-style="{ cursor: running ? 'not-allowed' : undefined }"
placement="top"
:default-value="tabs[0].name"
type="segment"
:value="selectedTab"
@update:value="
(val) => {
if (tabs.findIndex((t) => t.name === val) !== -1) {
if (!running && tabs.findIndex((t) => t.name === val) !== -1) {
selectedTab = val;
}
}
@ -44,15 +46,9 @@ const showHeader = ref(true);
<n-tab v-for="tab in tabs" :name="tab.name" />
</n-tabs>
</div>
<div class="display-header-button" @click="showHeader = !showHeader">
<n-icon size="18">
<ion-chevron-up v-if="showHeader" />
<ion-chevron-down v-else />
</n-icon>
</div>
<div class="main-content">
<keep-alive>
<Component :is="currentComponent" />
<Component :is="currentComponent" @start="running = true" @stop="running = false" />
</keep-alive>
</div>
</div>
@ -74,26 +70,6 @@ const showHeader = ref(true);
border-bottom: 1px solid #eaeaea;
}
.display-header-button {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
cursor: pointer;
> .n-icon {
opacity: 0.3;
}
&:hover {
> .n-icon {
opacity: 1;
}
background-color: #f7f7f7;
}
}
.main-content {
flex: 1;
width: 100%;