Skip to content

Commit

Permalink
fix: speed up to sync theme settings (#8440)
Browse files Browse the repository at this point in the history
* fix: remove watcher warnings

* refactor: naming

* refactor: speed up twitter DB accessing

* refactor: remove unnecessary delay
  • Loading branch information
guanbinrui committed Jan 10, 2023
1 parent f17760e commit f348da3
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,15 @@ import {
selfInfoSelectors,
} from '../utils/selector.js'

function recognizeDesktop() {
const collect = () => {
const handle = selfInfoSelectors().handle.evaluate()
const nickname = selfInfoSelectors().name.evaluate()
const avatar = selfInfoSelectors().userAvatar.evaluate()
function collectSelfInfo() {
const handle = selfInfoSelectors().handle.evaluate()
const nickname = selfInfoSelectors().name.evaluate()
const avatar = selfInfoSelectors().userAvatar.evaluate()

return { handle, nickname, avatar }
}

const watcher = new MutationObserverWatcher(selfInfoSelectors().handle)

return { watcher, collect }
return { handle, nickname, avatar }
}

function _getNickname(nickname?: string) {
function getNickname(nickname?: string) {
const nicknameNode = searchSelfNicknameSelector().closest<HTMLDivElement>(1).evaluate()
let _nickname = ''
if (!nicknameNode?.childNodes.length) return nickname
Expand All @@ -54,12 +48,11 @@ function resolveLastRecognizedIdentityInner(
) {
const assign = async () => {
await delay(2000)
const { collect } = recognizeDesktop()
const dataFromScript = collect()
const avatar = (searchSelfAvatarSelector().evaluate()?.getAttribute('src') || dataFromScript.avatar) ?? ''
const handle =
searchSelfHandleSelector().evaluate()?.textContent?.trim()?.replace(/^@/, '') || dataFromScript.handle
const nickname = _getNickname(dataFromScript.nickname) ?? ''

const selfInfo = collectSelfInfo()
const avatar = (searchSelfAvatarSelector().evaluate()?.getAttribute('src') || selfInfo.avatar) ?? ''
const handle = searchSelfHandleSelector().evaluate()?.textContent?.trim()?.replace(/^@/, '') || selfInfo.handle
const nickname = getNickname(selfInfo.nickname) ?? ''

if (handle) {
ref.value = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { delay } from '@masknet/kit'
import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
import { createLookupTableResolver } from '@masknet/shared-base'
import type { SocialNetworkUI as Next } from '@masknet/types'
Expand Down Expand Up @@ -45,7 +44,6 @@ async function resolveThemeSettingsInner(
cancel: AbortSignal,
) {
const assign = async () => {
await delay(2000)
const userSettings = await Twitter.getUserSettings(true)
if (!userSettings) return

Expand Down
35 changes: 35 additions & 0 deletions packages/web3-providers/src/Twitter/apis/getDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { memoize } from 'lodash-es'
import { memoizePromise } from '@masknet/kit'
import { isFirefox } from '@masknet/shared-base'

/* cspell:disable-next-line */
const DB_NAME = 'localforage'
const DB_VERSION = 2

export async function getDatabase() {
if (!isFirefox()) {
const databases = await indexedDB.databases()
if (!databases.some((x) => x.name === DB_NAME && x.version === DB_VERSION)) return
}

return new Promise<IDBDatabase>((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION)

request.addEventListener('success', () => {
resolve(request.result)
})
request.addEventListener('error', (error) => {
reject(error)
})
})
}

export async function getStore(name: string) {
const database = await getDatabase()
if (!database) throw new Error('Failed to read database.')

const transaction = database.transaction([name], 'readonly')
return transaction.objectStore(name)
}

export const getStoreCached = memoizePromise(memoize, getStore, (name) => name)
36 changes: 10 additions & 26 deletions packages/web3-providers/src/Twitter/apis/getUserSettings.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,28 @@
import { memoize } from 'lodash-es'
import { memoizePromise } from '@masknet/kit'
import { isFirefox } from '@masknet/shared-base'
import { TwitterBaseAPI } from '../../entry-types.js'
import { getStore } from './getDatabase.js'

/* cspell:disable-next-line */
const DB_NAME = 'localforage'
const DB_VERSION = 2
/* cspell:disable-next-line */
const STORE_NAME = 'keyvaluepairs'
/* cspell:disable-next-line */
const KEY_NAME = 'device:rweb.settings'

export async function getUserSettings() {
if (!isFirefox()) {
const databases = await indexedDB.databases()
if (!databases.some((x) => x.name === DB_NAME && x.version === DB_VERSION)) return
}
const store = await getStore(STORE_NAME)
const query = store.get(KEY_NAME)

return new Promise<TwitterBaseAPI.UserSettings | undefined>(async (resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION)

request.addEventListener('success', () => {
const db = request.result
const transaction = db.transaction([STORE_NAME], 'readonly')
const objectStore = transaction.objectStore(STORE_NAME)
const query = objectStore.get(KEY_NAME)
query.addEventListener('success', (event) => {
if (!event.target) reject('Failed to get user settings.')

query.addEventListener('success', (event) => {
if (!event.target) reject('Failed to get user settings.')
const event_ = event as unknown as TwitterBaseAPI.Event<{
local: TwitterBaseAPI.UserSettings
}>

const event_ = event as unknown as TwitterBaseAPI.Event<{
local: TwitterBaseAPI.UserSettings
}>
resolve(event_.target.result.local)
})
query.addEventListener('error', (error) => {
reject(error)
})
resolve(event_.target.result.local)
})
request.addEventListener('error', (error) => {
query.addEventListener('error', (error) => {
reject(error)
})
})
Expand Down
1 change: 1 addition & 0 deletions packages/web3-providers/src/Twitter/apis/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './getDatabase.js'
export * from './getSettings.js'
export * from './getTokens.js'
export * from './getUserNFTContainer.js'
Expand Down
18 changes: 6 additions & 12 deletions packages/web3-providers/src/Twitter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,18 @@ const TWITTER_AVATAR_ID_MATCH = /^\/profile_images\/(\d+)/
export class TwitterAPI implements TwitterBaseAPI.Provider {
getAvatarId(avatarURL?: string) {
if (!avatarURL) return ''
const url = new URL(avatarURL)
const match = url.pathname.match(TWITTER_AVATAR_ID_MATCH)
if (!match) return ''

return match[1]
const match = new URL(avatarURL).pathname.match(TWITTER_AVATAR_ID_MATCH)
return match ? match[1] : ''
}

getSettings() {
return getSettings()
}

async getUserSettings(fresh = false) {
const defaults = getDefaultUserSettings()
try {
if (fresh) await this.staleUserSettings()
if (fresh) getUserSettingsCached.cache.clear()
const userSettings = await timeout(getUserSettingsCached(), 5000)
return {
...defaults,
Expand All @@ -46,10 +44,6 @@ export class TwitterAPI implements TwitterBaseAPI.Provider {
}
}

async staleUserSettings() {
getUserSettingsCached.cache.clear()
}

async getUserNftContainer(screenName: string) {
const result = await attemptUntil<TwitterBaseAPI.NFT | undefined>(
[
Expand Down Expand Up @@ -101,9 +95,9 @@ export class TwitterAPI implements TwitterBaseAPI.Provider {
credentials: 'include',
headers,
})
const mediaId = initRes.media_id_string
// APPEND

// APPEND
const mediaId = initRes.media_id_string
const appendURL = `${UPLOAD_AVATAR_URL}?command=APPEND&media_id=${mediaId}&segment_index=0`
const formData = new FormData()
formData.append('media', image)
Expand Down
1 change: 0 additions & 1 deletion packages/web3-providers/src/types/Twitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ export namespace TwitterBaseAPI {
export interface Provider {
getSettings: () => Promise<Settings | undefined>
getUserSettings: () => Promise<UserSettings>
staleUserSettings: () => Promise<void>
/**
* @param screenName
* @param checkNFTAvatar With `checkNFTAvatar` true, will get user via web API directly,
Expand Down

0 comments on commit f348da3

Please sign in to comment.