From c70c3aff78f92e122f8e8c54b28d1f37e4ee836d Mon Sep 17 00:00:00 2001
From: PiEgg <marksz@teamsz.xyz>
Date: Tue, 27 Jul 2021 00:15:11 +0800
Subject: [PATCH] :construction: WIP: add gallery db

---
 src/main/apis/app/system/index.ts     |  1 +
 src/main/apis/core/datastore/index.ts | 18 ++++++++-
 src/main/events/picgoCoreIPC.ts       | 53 ++++++++++++++++++++++++++-
 src/main/lifeCycle/index.ts           | 12 +++---
 src/main/migrate/index.ts             | 26 +++++++++++--
 src/renderer/pages/Gallery.vue        | 51 ++++++++------------------
 src/renderer/utils/db.ts              |  6 +--
 src/universal/types/types.d.ts        |  1 +
 8 files changed, 118 insertions(+), 50 deletions(-)

diff --git a/src/main/apis/app/system/index.ts b/src/main/apis/app/system/index.ts
index ee83c47..f70a1cb 100644
--- a/src/main/apis/app/system/index.ts
+++ b/src/main/apis/app/system/index.ts
@@ -221,6 +221,7 @@ export function createTray () {
           setTimeout(() => {
             notification.show()
           }, i * 100)
+          // FIXME: gallery db
           db.insert('uploaded', imgs[i])
         }
         handleCopyUrl(pasteText.join('\n'))
diff --git a/src/main/apis/core/datastore/index.ts b/src/main/apis/core/datastore/index.ts
index 68db685..ee14ede 100644
--- a/src/main/apis/core/datastore/index.ts
+++ b/src/main/apis/core/datastore/index.ts
@@ -77,13 +77,27 @@ class ConfigStore {
     // @ts-ignore
     return this.read().get(key).removeById(id).write()
   }
+  getConfigPath () {
+    return CONFIG_PATH
+  }
 }
 
 export default new ConfigStore()
 
 // v2.3.0 add gallery db
-const dbStore = new DBStore(DB_PATH, 'gallery')
+class GalleryDB {
+  private static instance: DBStore
+  private constructor () {
+    console.log('init gallery db')
+  }
+  public static getInstance (): DBStore {
+    if (!GalleryDB.instance) {
+      GalleryDB.instance = new DBStore(DB_PATH, 'gallery')
+    }
+    return GalleryDB.instance
+  }
+}
 
 export {
-  dbStore
+  GalleryDB
 }
diff --git a/src/main/events/picgoCoreIPC.ts b/src/main/events/picgoCoreIPC.ts
index 4745467..c118906 100644
--- a/src/main/events/picgoCoreIPC.ts
+++ b/src/main/events/picgoCoreIPC.ts
@@ -16,7 +16,19 @@ import { IGuiMenuItem } from 'picgo/dist/src/types'
 import windowManager from 'apis/app/window/windowManager'
 import { IWindowList } from 'apis/app/window/constants'
 import { showNotification } from '~/main/utils/common'
-import { PICGO_SAVE_CONFIG, PICGO_GET_CONFIG } from '#/events/constants'
+import {
+  PICGO_SAVE_CONFIG,
+  PICGO_GET_CONFIG,
+  PICGO_GET_DB,
+  PICGO_INSERT_DB,
+  PICGO_INSERT_MANY_DB,
+  PICGO_UPDATE_BY_ID_DB,
+  PICGO_GET_BY_ID_DB,
+  PICGO_REMOVE_BY_ID_DB
+} from '#/events/constants'
+
+import { GalleryDB } from 'apis/core/datastore'
+import { IObject } from '@picgo/store/dist/types'
 
 // eslint-disable-next-line
 const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
@@ -270,6 +282,44 @@ const handleImportLocalPlugin = () => {
   })
 }
 
+const handlePicGoGalleryDB = () => {
+  ipcMain.on(PICGO_GET_DB, async (event: IpcMainEvent, callbackId: string) => {
+    const dbStore = GalleryDB.getInstance()
+    const res = await dbStore.get()
+    event.sender.send(PICGO_GET_CONFIG, res, callbackId)
+  })
+
+  ipcMain.on(PICGO_INSERT_DB, async (event: IpcMainEvent, value: IObject, callbackId: string) => {
+    const dbStore = GalleryDB.getInstance()
+    const res = await dbStore.insert(value)
+    event.sender.send(PICGO_INSERT_DB, res, callbackId)
+  })
+
+  ipcMain.on(PICGO_INSERT_MANY_DB, async (event: IpcMainEvent, value: IObject[], callbackId: string) => {
+    const dbStore = GalleryDB.getInstance()
+    const res = await dbStore.insertMany(value)
+    event.sender.send(PICGO_INSERT_MANY_DB, res, callbackId)
+  })
+
+  ipcMain.on(PICGO_UPDATE_BY_ID_DB, async (event: IpcMainEvent, id: string, value: IObject[], callbackId: string) => {
+    const dbStore = GalleryDB.getInstance()
+    const res = await dbStore.updateById(id, value)
+    event.sender.send(PICGO_UPDATE_BY_ID_DB, res, callbackId)
+  })
+
+  ipcMain.on(PICGO_GET_BY_ID_DB, async (event: IpcMainEvent, id: string, callbackId: string) => {
+    const dbStore = GalleryDB.getInstance()
+    const res = await dbStore.getById(id)
+    event.sender.send(PICGO_GET_BY_ID_DB, res, callbackId)
+  })
+
+  ipcMain.on(PICGO_REMOVE_BY_ID_DB, async (event: IpcMainEvent, id: string, callbackId: string) => {
+    const dbStore = GalleryDB.getInstance()
+    const res = await dbStore.removeById(id)
+    event.sender.send(PICGO_REMOVE_BY_ID_DB, res, callbackId)
+  })
+}
+
 export default {
   listen () {
     handleGetPluginList()
@@ -281,6 +331,7 @@ export default {
     handleRemoveFiles()
     handlePicGoSaveConfig()
     handlePicGoGetConfig()
+    handlePicGoGalleryDB()
     handleImportLocalPlugin()
   }
 }
diff --git a/src/main/lifeCycle/index.ts b/src/main/lifeCycle/index.ts
index 33b0f5a..4fa488e 100644
--- a/src/main/lifeCycle/index.ts
+++ b/src/main/lifeCycle/index.ts
@@ -16,7 +16,8 @@ import busEventList from '~/main/events/busEventList'
 import { IWindowList } from 'apis/app/window/constants'
 import windowManager from 'apis/app/window/windowManager'
 import {
-  updateShortKeyFromVersion212
+  updateShortKeyFromVersion212,
+  migrateGalleryFromVersion230
 } from '~/main/migrate'
 import {
   uploadChoosedFiles,
@@ -29,7 +30,7 @@ import server from '~/main/server/index'
 import updateChecker from '~/main/utils/updateChecker'
 import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
 import { getUploadFiles } from '~/main/utils/handleArgv'
-import db from '~/main/apis/core/datastore'
+import db, { GalleryDB } from '~/main/apis/core/datastore'
 import bus from '@core/bus'
 import { privacyManager } from '~/main/utils/privacyManager'
 import logger from 'apis/core/picgo/logger'
@@ -54,7 +55,7 @@ const handleStartUpFiles = (argv: string[], cwd: string) => {
 }
 
 class LifeCycle {
-  private beforeReady () {
+  private async beforeReady () {
     protocol.registerSchemesAsPrivileged([{ scheme: 'picgo', privileges: { secure: true, standard: true } }])
     // fix the $PATH in macOS
     fixPath()
@@ -62,6 +63,7 @@ class LifeCycle {
     ipcList.listen()
     busEventList.listen()
     updateShortKeyFromVersion212(db, db.get('settings.shortKey'))
+    await migrateGalleryFromVersion230(db, GalleryDB.getInstance())
   }
   private onReady () {
     app.on('ready', async () => {
@@ -162,12 +164,12 @@ class LifeCycle {
       }
     }
   }
-  launchApp () {
+  async launchApp () {
     const gotTheLock = app.requestSingleInstanceLock()
     if (!gotTheLock) {
       app.quit()
     } else {
-      this.beforeReady()
+      await this.beforeReady()
       this.onReady()
       this.onRunning()
       this.onQuit()
diff --git a/src/main/migrate/index.ts b/src/main/migrate/index.ts
index 8746dff..dc8ee08 100644
--- a/src/main/migrate/index.ts
+++ b/src/main/migrate/index.ts
@@ -1,6 +1,9 @@
-import DB from '~/main/apis/core/datastore'
+import { DBStore } from '@picgo/store'
+import ConfigStore from '~/main/apis/core/datastore'
+import path from 'path'
+import fse from 'fs-extra'
 // from v2.1.2
-const updateShortKeyFromVersion212 = (db: typeof DB, shortKeyConfig: IShortKeyConfigs | IOldShortKeyConfigs) => {
+const updateShortKeyFromVersion212 = (db: typeof ConfigStore, shortKeyConfig: IShortKeyConfigs | IOldShortKeyConfigs) => {
   // #557 极端情况可能会出现配置不存在,需要重新写入
   if (shortKeyConfig === undefined) {
     const defaultShortKeyConfig = {
@@ -28,6 +31,21 @@ const updateShortKeyFromVersion212 = (db: typeof DB, shortKeyConfig: IShortKeyCo
   return false
 }
 
-export {
-  updateShortKeyFromVersion212
+const migrateGalleryFromVersion230 = async (configDB: typeof ConfigStore, galleryDB: DBStore) => {
+  const originGallery: ImgInfo[] = configDB.get('uploaded')
+  const configPath = configDB.getConfigPath()
+  const configBakPath = path.join(path.dirname(configPath), 'config-bak.json')
+  if (fse.existsSync(configBakPath)) {
+    return
+  }
+  fse.copyFileSync(configPath, configBakPath)
+  // migrate gallery from config to gallery db
+  if (originGallery && originGallery.length > 0) {
+    await galleryDB.insertMany(originGallery)
+  }
+}
+
+export {
+  updateShortKeyFromVersion212,
+  migrateGalleryFromVersion230
 }
diff --git a/src/renderer/pages/Gallery.vue b/src/renderer/pages/Gallery.vue
index b779d94..deff3ed 100644
--- a/src/renderer/pages/Gallery.vue
+++ b/src/renderer/pages/Gallery.vue
@@ -159,14 +159,15 @@ export default class extends Vue {
       this.clearChoosedList()
     }
   }
-  created () {
+  async created () {
     ipcRenderer.on('updateGallery', (event: IpcRendererEvent) => {
-      this.$nextTick(() => {
-        this.filterList = this.getGallery()
+      this.$nextTick(async () => {
+        this.images = await this.$$db.get()
       })
     })
     ipcRenderer.send('getPicBeds')
     ipcRenderer.on('getPicBeds', this.getPicBeds)
+    this.images = await this.$$db.get()
   }
   mounted () {
     document.addEventListener('keydown', this.handleDetectShiftKey)
@@ -180,9 +181,6 @@ export default class extends Vue {
   get filterList () {
     return this.getGallery()
   }
-  set filterList (val) {
-    this.images = val
-  }
   get isAllSelected () {
     const values = Object.values(this.choosedList)
     if (values.length === 0) {
@@ -196,38 +194,21 @@ export default class extends Vue {
   getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
     this.picBed = picBeds
   }
-  // FIXME: gallery db && async computed - -||.....
-  getGallery () {
-    if (this.choosedPicBed.length > 0) {
-      let arr: ImgInfo[] = []
-      this.choosedPicBed.forEach(item => {
-        let obj: IObj = {
-          type: item
-        }
-        if (this.searchText) {
-          obj.fileName = this.searchText
-        }
-        arr = arr.concat(this.$db.read().get('uploaded').filter(obj => {
-          return obj.fileName.indexOf(this.searchText) !== -1 && obj.type === item
-        }).reverse().value())
-      })
-      this.images = arr
+  getGallery (): ImgInfo[] {
+    if (this.searchText || this.choosedPicBed.length > 0) {
+      return this.images
+        .filter(item => {
+          let isInChoosedPicBed = true
+          if (this.choosedPicBed.length > 0) {
+            isInChoosedPicBed = this.choosedPicBed.some(type => type === item.type)
+          }
+          return item.fileName?.includes(this.searchText) && isInChoosedPicBed
+        })
     } else {
-      if (this.searchText) {
-        // FIXME: gallery db
-        let data = this.$db.read().get('uploaded')
-        // @ts-ignore
-          .filter(item => {
-            return item.fileName.indexOf(this.searchText) !== -1
-          }).reverse().value()
-        this.images = data
-      } else {
-        // FIXME: gallery db
-        this.images = this.$db.read().get('uploaded').slice().reverse().value()
-      }
+      return this.images
     }
-    return this.images
   }
+
   @Watch('filterList')
   handleFilterListChange () {
     this.clearChoosedList()
diff --git a/src/renderer/utils/db.ts b/src/renderer/utils/db.ts
index d0bc37d..0772bf2 100644
--- a/src/renderer/utils/db.ts
+++ b/src/renderer/utils/db.ts
@@ -27,8 +27,8 @@ export class GalleryDB implements IGalleryDB {
     const res = await this.msgHandler<boolean>(PICGO_UPDATE_BY_ID_DB, id, value)
     return res
   }
-  async getById (id: string): Promise<IObject | undefined> {
-    const res = await this.msgHandler<IObject | undefined>(PICGO_GET_BY_ID_DB, id)
+  async getById<T> (id: string): Promise<IResult<T> | undefined> {
+    const res = await this.msgHandler<IResult<T> | undefined>(PICGO_GET_BY_ID_DB, id)
     return res
   }
   async removeById (id: string): Promise<void> {
@@ -45,7 +45,7 @@ export class GalleryDB implements IGalleryDB {
         }
       }
       ipcRenderer.on(method, callback)
-      ipcRenderer.send(method, ...args)
+      ipcRenderer.send(method, ...args, callbackId)
     })
   }
 }
diff --git a/src/universal/types/types.d.ts b/src/universal/types/types.d.ts
index 9802781..4ec685e 100644
--- a/src/universal/types/types.d.ts
+++ b/src/universal/types/types.d.ts
@@ -45,6 +45,7 @@ interface ImgInfo {
   extname?: string
   imgUrl?: string
   id?: string
+  type?: string
   [propName: string]: any
 }