mirror of
https://github.com/h3poteto/whalebird-desktop
synced 2025-02-03 02:37:55 +01:00
Merge pull request #995 from h3poteto/iss-985
refs #985 Cache accounts and search cache when suggest
This commit is contained in:
commit
a09f17dc1a
38
src/main/cache/account.ts
vendored
Normal file
38
src/main/cache/account.ts
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
import { isEmpty } from 'lodash'
|
||||
import Datastore from 'nedb'
|
||||
import { CachedAccount } from '~/src/types/cachedAccount'
|
||||
|
||||
export default class AccountCache {
|
||||
private db: Datastore
|
||||
|
||||
constructor(path: string) {
|
||||
this.db = new Datastore({
|
||||
filename: path,
|
||||
autoload: true
|
||||
})
|
||||
}
|
||||
|
||||
listAccounts(ownerID: string): Promise<Array<CachedAccount>> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.find<CachedAccount>({ owner_id: ownerID }, (err, docs) => {
|
||||
if (err) return reject(err)
|
||||
resolve(docs)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
insertAccount(ownerID: string, acct: string): Promise<CachedAccount> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// At first confirm records for unique.
|
||||
this.db.findOne<CachedAccount>({ owner_id: ownerID, acct: acct }, (err, doc) => {
|
||||
if (err) return err
|
||||
// Ignore error for unique constraints.
|
||||
if (!isEmpty(doc)) return err
|
||||
return this.db.insert<CachedAccount>({ owner_id: ownerID, acct: acct }, (err, doc) => {
|
||||
if (err) return reject(err)
|
||||
return resolve(doc)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
@ -41,6 +41,8 @@ import { UnreadNotification as UnreadNotificationConfig } from '~/src/types/unre
|
||||
import { Notify } from '~/src/types/notify'
|
||||
import { StreamingError } from '~/src/errors/streamingError'
|
||||
import HashtagCache from './cache/hashtag'
|
||||
import AccountCache from './cache/account'
|
||||
import { InsertAccountCache } from '~/src/types/insertAccountCache'
|
||||
|
||||
/**
|
||||
* Context menu
|
||||
@ -107,6 +109,9 @@ const preferencesDBPath = process.env.NODE_ENV === 'production' ? userData + './
|
||||
const hashtagCachePath = process.env.NODE_ENV === 'production' ? userData + '/cache/hashtag.db' : 'cache/hashtag.db'
|
||||
const hashtagCache = new HashtagCache(hashtagCachePath)
|
||||
|
||||
const accountCachePath = process.env.NODE_ENV === 'production' ? userData + '/cache/account.db' : 'cache/account.db'
|
||||
const accountCache = new AccountCache(accountCachePath)
|
||||
|
||||
const soundBasePath =
|
||||
process.env.NODE_ENV === 'development' ? path.join(__dirname, '../../build/sounds/') : path.join(process.resourcesPath!, 'build/sounds/')
|
||||
|
||||
@ -460,7 +465,7 @@ ipcMain.on('start-all-user-streamings', (event: Event, accounts: Array<LocalAcco
|
||||
const url = await StreamingURL(acct)
|
||||
userStreamings[id] = new WebSocket(acct, url)
|
||||
userStreamings[id]!.startUserStreaming(
|
||||
(update: Status) => {
|
||||
async (update: Status) => {
|
||||
if (!event.sender.isDestroyed()) {
|
||||
event.sender.send(`update-start-all-user-streamings-${id}`, update)
|
||||
}
|
||||
@ -468,6 +473,8 @@ ipcMain.on('start-all-user-streamings', (event: Event, accounts: Array<LocalAcco
|
||||
update.tags.map(async tag => {
|
||||
await hashtagCache.insertHashtag(tag.name)
|
||||
})
|
||||
// Cache account
|
||||
await accountCache.insertAccount(id, update.account.acct).catch(err => console.error(err))
|
||||
},
|
||||
(notification: RemoteNotification) => {
|
||||
const preferences = new Preferences(preferencesDBPath)
|
||||
@ -1005,7 +1012,20 @@ ipcMain.on('insert-cache-hashtags', (event: Event, tags: Array<string>) => {
|
||||
tags.map(async name => {
|
||||
await hashtagCache.insertHashtag(name)
|
||||
})
|
||||
event.sender.send('response-insert-cache-hashtag')
|
||||
event.sender.send('response-insert-cache-hashtags')
|
||||
})
|
||||
|
||||
ipcMain.on('get-cache-accounts', async (event: Event, ownerID: string) => {
|
||||
const accounts = await accountCache.listAccounts(ownerID)
|
||||
event.sender.send('response-get-cache-accounts', accounts)
|
||||
})
|
||||
|
||||
ipcMain.on('insert-cache-accounts', (event: Event, obj: InsertAccountCache) => {
|
||||
const { ownerID, accts } = obj
|
||||
accts.map(async acct => {
|
||||
await accountCache.insertAccount(ownerID, acct).catch(err => console.error(err))
|
||||
})
|
||||
event.sender.send('response-insert-cache-accounts')
|
||||
})
|
||||
|
||||
// Application control
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import emojilib from 'emojilib'
|
||||
import Mastodon, { Account, Tag, Response, Results } from 'megalodon'
|
||||
import Mastodon, { Response, Results } from 'megalodon'
|
||||
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
|
||||
import { RootState } from '@/store/index'
|
||||
import { LocalTag } from '~/src/types/localTag'
|
||||
import { InsertAccountCache } from '~/src/types/insertAccountCache'
|
||||
import { CachedAccount } from '~/src/types/cachedAccount'
|
||||
|
||||
type Suggest = {
|
||||
name: string
|
||||
@ -38,7 +40,7 @@ const state = (): StatusState => ({
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
UPDATE_FILTERED_ACCOUNTS: 'updateFilteredAccounts',
|
||||
APPEND_FILTERED_ACCOUNTS: 'appendFilteredAccounts',
|
||||
CLEAR_FILTERED_ACCOUNTS: 'clearFilteredAccounts',
|
||||
APPEND_FILTERED_HASHTAGS: 'appendFilteredHashtags',
|
||||
CLEAR_FILTERED_HASHTAGS: 'clearFilteredHashtags',
|
||||
@ -54,16 +56,17 @@ export const MUTATION_TYPES = {
|
||||
}
|
||||
|
||||
const mutations: MutationTree<StatusState> = {
|
||||
[MUTATION_TYPES.UPDATE_FILTERED_ACCOUNTS]: (state, accounts: Array<Account>) => {
|
||||
state.filteredAccounts = accounts.map(a => ({
|
||||
name: `@${a.acct}`,
|
||||
[MUTATION_TYPES.APPEND_FILTERED_ACCOUNTS]: (state, accounts: Array<string>) => {
|
||||
const appended = accounts.map(a => ({
|
||||
name: `@${a}`,
|
||||
image: null
|
||||
}))
|
||||
state.filteredAccounts = appended.filter((elem, index, self) => self.indexOf(elem) === index)
|
||||
},
|
||||
[MUTATION_TYPES.CLEAR_FILTERED_ACCOUNTS]: state => {
|
||||
state.filteredAccounts = []
|
||||
},
|
||||
[MUTATION_TYPES.APPEND_FILTERED_HASHTAGS]: (state, tags: Array<Tag>) => {
|
||||
[MUTATION_TYPES.APPEND_FILTERED_HASHTAGS]: (state, tags: Array<string>) => {
|
||||
const appended = tags.map(t => ({
|
||||
name: `#${t}`,
|
||||
image: null
|
||||
@ -109,15 +112,39 @@ const actions: ActionTree<StatusState, RootState> = {
|
||||
commit(MUTATION_TYPES.CLEAR_FILTERED_ACCOUNTS)
|
||||
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS)
|
||||
const { word, start } = wordStart
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
const res: Response<Results> = await client.get<Results>('/search', { q: word, resolve: false })
|
||||
commit(MUTATION_TYPES.UPDATE_FILTERED_ACCOUNTS, res.data.accounts)
|
||||
if (res.data.accounts.length === 0) throw new Error('Empty')
|
||||
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
|
||||
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
|
||||
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
|
||||
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS)
|
||||
return res.data.accounts
|
||||
const searchCache = () => {
|
||||
return new Promise(resolve => {
|
||||
const target = word.replace('@', '')
|
||||
ipcRenderer.once('response-get-cache-accounts', (_, accounts: Array<CachedAccount>) => {
|
||||
console.log(accounts)
|
||||
const matched = accounts.map(account => account.acct).filter(acct => acct.includes(target))
|
||||
if (matched.length === 0) throw new Error('Empty')
|
||||
commit(MUTATION_TYPES.APPEND_FILTERED_ACCOUNTS, matched)
|
||||
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
|
||||
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
|
||||
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
|
||||
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS)
|
||||
resolve(matched)
|
||||
})
|
||||
ipcRenderer.send('get-cache-accounts', rootState.TimelineSpace.account._id)
|
||||
})
|
||||
}
|
||||
const searchAPI = async () => {
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
const res: Response<Results> = await client.get<Results>('/search', { q: word, resolve: false })
|
||||
if (res.data.accounts.length === 0) throw new Error('Empty')
|
||||
commit(MUTATION_TYPES.APPEND_FILTERED_ACCOUNTS, res.data.accounts.map(account => account.acct))
|
||||
ipcRenderer.send('insert-cache-accounts', {
|
||||
ownerID: rootState.TimelineSpace.account._id!,
|
||||
accts: res.data.accounts.map(a => a.acct)
|
||||
} as InsertAccountCache)
|
||||
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
|
||||
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
|
||||
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
|
||||
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS)
|
||||
return res.data.accounts
|
||||
}
|
||||
await Promise.all([searchCache(), searchAPI()])
|
||||
},
|
||||
suggestHashtag: async ({ commit, rootState }, wordStart: WordStart) => {
|
||||
commit(MUTATION_TYPES.CLEAR_FILTERED_HASHTAGS)
|
||||
@ -127,14 +154,14 @@ const actions: ActionTree<StatusState, RootState> = {
|
||||
return new Promise(resolve => {
|
||||
const target = word.replace('#', '')
|
||||
ipcRenderer.once('response-get-cache-hashtags', (_, tags: Array<LocalTag>) => {
|
||||
const mached = tags.filter(tag => tag.tagName.includes(target)).map(tag => tag.tagName)
|
||||
commit(MUTATION_TYPES.APPEND_FILTERED_HASHTAGS, mached)
|
||||
if (mached.length === 0) throw new Error('Empty')
|
||||
const matched = tags.map(tag => tag.tagName).filter(tag => tag.includes(target))
|
||||
if (matched.length === 0) throw new Error('Empty')
|
||||
commit(MUTATION_TYPES.APPEND_FILTERED_HASHTAGS, matched)
|
||||
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
|
||||
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
|
||||
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
|
||||
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_HASHTAGS)
|
||||
resolve(mached)
|
||||
resolve(matched)
|
||||
})
|
||||
ipcRenderer.send('get-cache-hashtags')
|
||||
})
|
||||
@ -143,8 +170,8 @@ const actions: ActionTree<StatusState, RootState> = {
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
const res: Response<Results> = await client.get<Results>('/search', { q: word })
|
||||
commit(MUTATION_TYPES.APPEND_FILTERED_HASHTAGS, res.data.hashtags)
|
||||
ipcRenderer.send('insert-cache-hashtags', res.data.hashtags)
|
||||
if (res.data.hashtags.length === 0) throw new Error('Empty')
|
||||
ipcRenderer.send('insert-cache-hashtags', res.data.hashtags)
|
||||
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
|
||||
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
|
||||
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
|
||||
|
5
src/types/cachedAccount.ts
Normal file
5
src/types/cachedAccount.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export type CachedAccount = {
|
||||
_id?: string
|
||||
acct: string
|
||||
owner_id: string
|
||||
}
|
4
src/types/insertAccountCache.ts
Normal file
4
src/types/insertAccountCache.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export type InsertAccountCache = {
|
||||
ownerID: string
|
||||
accts: Array<string>
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user