Skip to content

Commit

Permalink
no message
Browse files Browse the repository at this point in the history
  • Loading branch information
153264 committed Jun 20, 2024
1 parent 5151dfd commit eb49966
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 10 deletions.
55 changes: 52 additions & 3 deletions web/src/data/local/LocalVolumeDao.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { deleteDB, DBSchema, openDB } from 'idb';
import { DBSchema, openDB } from 'idb';

import { LocalVolumeChapter, LocalVolumeMetadata } from '@/model/LocalVolume';
import { LocalVolumeChapter, LocalVolumeMetadata, LocalVolumeFavorite } from '@/model/LocalVolume';

type Mutator<T> = (value: T) => T;

interface VolumesDBSchema extends DBSchema {
favorite: {
key: string;
value: LocalVolumeFavorite;
}
metadata: {
key: string;
value: LocalVolumeMetadata;
Expand All @@ -24,17 +28,55 @@ interface VolumesDBSchema extends DBSchema {
}

export const createLocalVolumeDao = async () => {
const db = await openDB<VolumesDBSchema>('volumes', 1, {
const db = await openDB<VolumesDBSchema>('volumes', 2, {
upgrade(db, oldVersion, _newVersion, _transaction, _event) {
if (oldVersion <= 0) {
db.createObjectStore('metadata', { keyPath: 'id' });
db.createObjectStore('file', { keyPath: 'id' });
const store = db.createObjectStore('chapter', { keyPath: 'id' });
store.createIndex('byVolumeId', 'volumeId');
}
if (oldVersion <= 1) {
const favorite = db.createObjectStore('favorite', { keyPath: 'id' });
favorite.put({
id: 'default',
title: '默认收藏夹'
});
}
},
});

//favored
const listFavorite = () => db.getAll('favorite');
const getFavorite = (id: string) => db.get('favorite', id);
const deleteFavorite = async (id: string) => {
const list = await listMetadata()
await Promise.all(list.map(async it => {
if (it.favoriteId === id) {
await updateMetadata(it.id, (value) => {
delete value.favoriteId
return value
})
}
}))
return db.delete('favorite', id)
};
const createFavorite = (value: LocalVolumeFavorite) =>
db.put('favorite', value);
const updateFavorite = async (
id: string,
mutator: Mutator<LocalVolumeFavorite>,
) => {
const tx = db.transaction('favorite', 'readwrite');
let value = await tx.store.get(id);
if (value !== undefined) {
value = mutator(value);
await tx.store.put(value);
}
await tx.done;
return value;
};

//Metadata
const listMetadata = () => db.getAll('metadata');
const getMetadata = (id: string) => db.get('metadata', id);
Expand Down Expand Up @@ -88,6 +130,13 @@ export const createLocalVolumeDao = async () => {
};

return {
//
listFavorite,
getFavorite,
deleteFavorite,
createFavorite,
updateFavorite,
//
listMetadata,
getMetadata,
deleteMetadata,
Expand Down
7 changes: 7 additions & 0 deletions web/src/data/local/LocalVolumeRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export const createLocalVolumeRepository = async () => {
return value;
});

const updateFavoriteId = (id: string, favoriteId: string) =>
dao.updateMetadata(id, (value) => {
value.favoriteId = favoriteId;
return value
})

const updateTranslation = async (
id: string,
chapterId: string,
Expand Down Expand Up @@ -84,6 +90,7 @@ export const createLocalVolumeRepository = async () => {
deleteVolume,
updateGlossary,
updateReadAt,
updateFavoriteId,
//
getChapter: dao.getChapter,
updateTranslation,
Expand Down
6 changes: 6 additions & 0 deletions web/src/model/LocalVolume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface LocalVolumeMetadata {
}[];
glossaryId: string;
glossary: Glossary;
favoriteId?: string;
}

export interface LocalVolumeChapter {
Expand All @@ -30,3 +31,8 @@ export interface LocalVolumeChapter {
gpt?: ChapterTranslation;
sakura?: ChapterTranslation;
}

export interface LocalVolumeFavorite {
id: string;
title: string;
}
1 change: 1 addition & 0 deletions web/src/pages/bookshelf/BookshelfLocal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const bookshelfListRef = ref<InstanceType<typeof BookshelfList>>();

<bookshelf-local-list
ref="bookshelfListRef"
:favoredId="favoredId"
:selectable="showControlPanel"
/>
</bookshelf-layout>
Expand Down
17 changes: 14 additions & 3 deletions web/src/pages/bookshelf/BookshelfStore.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Locator } from '@/data';
import { createLocalVolumeDao } from '@/data/local';
import { Favored } from '@/model/User';
import { v4 as uuidv4 } from 'uuid';

type BookshelfStore = {
web: Favored[];
wenku: Favored[];
local: Favored[];
};

const dao = await createLocalVolumeDao()

export const useBookshelfStore = defineStore('Bookshelf', {
state: () =>
<BookshelfStore>{
Expand All @@ -22,14 +26,18 @@ export const useBookshelfStore = defineStore('Bookshelf', {
this.web = favoredList.web;
this.wenku = favoredList.wenku;
}
this.local = (await dao.listFavorite()).reverse()
},
async createFavored(type: 'web' | 'wenku' | 'local', title: string) {
if (type === 'web') {
await Locator.userRepository.createFavoredWeb({ title });
} else if (type === 'wenku') {
await Locator.userRepository.createFavoredWenku({ title });
} else {
// 未完成
await dao.createFavorite({
id: uuidv4(),
title
});
}
await this.loadFavoredList();
},
Expand All @@ -43,7 +51,10 @@ export const useBookshelfStore = defineStore('Bookshelf', {
} else if (type === 'wenku') {
await Locator.userRepository.updateFavoredWenku(id, { title });
} else {
// 未完成
await dao.updateFavorite(id, (value) => {
value.title = title
return value
})
}
const favored = this[type].find((it) => it.id === id);
if (favored) {
Expand All @@ -56,7 +67,7 @@ export const useBookshelfStore = defineStore('Bookshelf', {
} else if (type === 'wenku') {
await Locator.userRepository.deleteFavoredWenku(id);
} else {
// 未完成
await dao.deleteFavorite(id)
}
this[type] = this[type].filter((it) => it.id !== id);
},
Expand Down
10 changes: 8 additions & 2 deletions web/src/pages/bookshelf/components/BookshelfAddButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ const store = useBookshelfStore();
const showAddModal = ref(false);
interface Value {
title: string;
type: 'web' | 'wenku' | 'local';
}
const formRef = ref<FormInst>();
const formValue = ref({
const formValue = ref<Value>({
title: '',
type: 'web' as 'web' | 'wenku',
type: 'web',
});
const formRules: FormRules = {
title: [
Expand Down Expand Up @@ -67,6 +72,7 @@ const addFavorite = async () => {
<n-flex>
<n-radio value="web"> 网页小说 </n-radio>
<n-radio value="wenku"> 文库小说 </n-radio>
<n-radio value="local"> 本地小说 </n-radio>
</n-flex>
</n-radio-group>
</n-form-item-row>
Expand Down
61 changes: 61 additions & 0 deletions web/src/pages/bookshelf/components/BookshelfLocalControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { Setting } from '@/model/Setting';
import { useIsWideScreen } from '@/pages/util';
import { useBookshelfLocalStore } from '../BookshelfLocalStore';
import { useBookshelfStore } from '../BookshelfStore';
const props = defineProps<{
selectedIds: string[];
favoredId: string;
}>();
defineEmits<{
selectAll: [];
Expand Down Expand Up @@ -63,6 +65,40 @@ const downloadRawSelected = async () => {
message.info(`${success}本小说原文被打包,${failed}本失败`);
};
// 移动小说
const bookshelfStore = useBookshelfStore();
const targetFavoredId = ref(props.favoredId);
const moveToFavored = async () => {
const novels = props.selectedIds;
if (novels.length === 0) {
message.info('没有选中小说');
return;
}
if (targetFavoredId.value === props.favoredId) {
message.info('无需移动');
return;
}
const localVolumeRepository = await Locator.localVolumeRepository();
let failed = 0;
await Promise.all(
novels.map(async (it) => {
try {
await localVolumeRepository.updateFavoriteId(it, targetFavoredId.value);
} catch (error) {
failed += 1;
}
}),
);
const success = novels.length - failed;
message.info(`${success}本小说已移动,${failed}本失败`);
window.location.reload();
};
// 生成翻译任务
const translateLevel = ref<'expire' | 'all'>('expire');
const reverseOrder = ref(false);
Expand Down Expand Up @@ -150,6 +186,31 @@ const queueJobs = (type: 'gpt' | 'sakura') => {
</n-flex>
</n-list-item>

<n-list-item v-if="bookshelfStore.local.length > 1">
<n-flex vertical>
<b>移动小说</b>

<n-radio-group v-model:value="targetFavoredId">
<n-flex align="center">
<c-button
label="移动"
size="small"
:round="false"
@action="moveToFavored"
/>

<n-radio
v-for="favored in bookshelfStore.local"
:key="favored.id"
:value="favored.id"
>
{{ favored.title }}
</n-radio>
</n-flex>
</n-radio-group>
</n-flex>
</n-list-item>

<n-list-item
v-if="
setting.enabledTranslator.includes('gpt') ||
Expand Down
7 changes: 6 additions & 1 deletion web/src/pages/bookshelf/components/BookshelfLocalList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
const props = defineProps<{
selectable?: boolean;
favoredId: string;
}>();
const { setting } = Locator.settingRepository();
Expand All @@ -24,7 +25,11 @@ const search = reactive({
});
const sortedVolumes = computed(() => {
return BookshelfLocalUtil.filterAndSortVolumes(volumes.value, {
let _volumes = volumes.value;
if (props.favoredId && props.favoredId != 'default') {
_volumes = _volumes.filter((v) => v.favoriteId == props.favoredId);
}
return BookshelfLocalUtil.filterAndSortVolumes(_volumes, {
...search,
order: setting.value.localVolumeOrder,
});
Expand Down
1 change: 0 additions & 1 deletion web/src/pages/bookshelf/components/BookshelfMenuItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ const deleteFavorite = () =>
<n-flex align="center" justify="space-between">
{{ title }}
<n-dropdown
v-if="type !== 'local'"
trigger="hover"
:options="options"
:keyboard="false"
Expand Down

0 comments on commit eb49966

Please sign in to comment.