refactor(frontend): アカウント情報はstore管理に
This commit is contained in:
		
							parent
							
								
									de19d9a4d4
								
							
						
					
					
						commit
						75267f87d5
					
				|  | @ -21,14 +21,19 @@ type AccountWithToken = Misskey.entities.MeDetailed & { token: string }; | ||||||
| 
 | 
 | ||||||
| export async function getAccounts(): Promise<{ | export async function getAccounts(): Promise<{ | ||||||
| 	host: string; | 	host: string; | ||||||
| 	user: Misskey.entities.User; | 	id: Misskey.entities.User['id']; | ||||||
|  | 	username: Misskey.entities.User['username']; | ||||||
|  | 	user?: Misskey.entities.User | null; | ||||||
| 	token: string | null; | 	token: string | null; | ||||||
| }[]> { | }[]> { | ||||||
| 	const tokens = store.s.accountTokens; | 	const tokens = store.s.accountTokens; | ||||||
|  | 	const accountInfos = store.s.accountInfos; | ||||||
| 	const accounts = prefer.s.accounts; | 	const accounts = prefer.s.accounts; | ||||||
| 	return accounts.map(([host, user]) => ({ | 	return accounts.map(([host, user]) => ({ | ||||||
| 		host, | 		host, | ||||||
| 		user, | 		id: user.id, | ||||||
|  | 		username: user.username, | ||||||
|  | 		user: accountInfos[host + '/' + user.id], | ||||||
| 		token: tokens[host + '/' + user.id] ?? null, | 		token: tokens[host + '/' + user.id] ?? null, | ||||||
| 	})); | 	})); | ||||||
| } | } | ||||||
|  | @ -36,7 +41,8 @@ export async function getAccounts(): Promise<{ | ||||||
| async function addAccount(host: string, user: Misskey.entities.User, token: AccountWithToken['token']) { | async function addAccount(host: string, user: Misskey.entities.User, token: AccountWithToken['token']) { | ||||||
| 	if (!prefer.s.accounts.some(x => x[0] === host && x[1].id === user.id)) { | 	if (!prefer.s.accounts.some(x => x[0] === host && x[1].id === user.id)) { | ||||||
| 		store.set('accountTokens', { ...store.s.accountTokens, [host + '/' + user.id]: token }); | 		store.set('accountTokens', { ...store.s.accountTokens, [host + '/' + user.id]: token }); | ||||||
| 		prefer.commit('accounts', [...prefer.s.accounts, [host, user]]); | 		store.set('accountInfos', { ...store.s.accountInfos, [host + '/' + user.id]: user }); | ||||||
|  | 		prefer.commit('accounts', [...prefer.s.accounts, [host, { id: user.id, username: user.username }]]); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -44,6 +50,10 @@ export async function removeAccount(host: string, id: AccountWithToken['id']) { | ||||||
| 	const tokens = JSON.parse(JSON.stringify(store.s.accountTokens)); | 	const tokens = JSON.parse(JSON.stringify(store.s.accountTokens)); | ||||||
| 	delete tokens[host + '/' + id]; | 	delete tokens[host + '/' + id]; | ||||||
| 	store.set('accountTokens', tokens); | 	store.set('accountTokens', tokens); | ||||||
|  | 	const accountInfos = JSON.parse(JSON.stringify(store.s.accountInfos)); | ||||||
|  | 	delete accountInfos[host + '/' + id]; | ||||||
|  | 	store.set('accountInfos', accountInfos); | ||||||
|  | 
 | ||||||
| 	prefer.commit('accounts', prefer.s.accounts.filter(x => x[0] !== host || x[1].id !== id)); | 	prefer.commit('accounts', prefer.s.accounts.filter(x => x[0] !== host || x[1].id !== id)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -121,14 +131,7 @@ export function updateCurrentAccount(accountData: Misskey.entities.MeDetailed) { | ||||||
| 	for (const [key, value] of Object.entries(accountData)) { | 	for (const [key, value] of Object.entries(accountData)) { | ||||||
| 		$i[key] = value; | 		$i[key] = value; | ||||||
| 	} | 	} | ||||||
| 	prefer.commit('accounts', prefer.s.accounts.map(([host, user]) => { | 	store.set('accountInfos', { ...store.s.accountInfos, [host + '/' + $i.id]: $i }); | ||||||
| 		// TODO: $iのホストも比較したいけど通常null
 |  | ||||||
| 		if (user.id === $i.id) { |  | ||||||
| 			return [host, $i]; |  | ||||||
| 		} else { |  | ||||||
| 			return [host, user]; |  | ||||||
| 		} |  | ||||||
| 	})); |  | ||||||
| 	$i.token = token; | 	$i.token = token; | ||||||
| 	miLocalStorage.setItem('account', JSON.stringify($i)); | 	miLocalStorage.setItem('account', JSON.stringify($i)); | ||||||
| } | } | ||||||
|  | @ -138,17 +141,9 @@ export function updateCurrentAccountPartial(accountData: Partial<Misskey.entitie | ||||||
| 	for (const [key, value] of Object.entries(accountData)) { | 	for (const [key, value] of Object.entries(accountData)) { | ||||||
| 		$i[key] = value; | 		$i[key] = value; | ||||||
| 	} | 	} | ||||||
| 	prefer.commit('accounts', prefer.s.accounts.map(([host, user]) => { | 
 | ||||||
| 		// TODO: $iのホストも比較したいけど通常null
 | 	store.set('accountInfos', { ...store.s.accountInfos, [host + '/' + $i.id]: $i }); | ||||||
| 		if (user.id === $i.id) { | 
 | ||||||
| 			const newUser = JSON.parse(JSON.stringify($i)); |  | ||||||
| 			for (const [key, value] of Object.entries(accountData)) { |  | ||||||
| 				newUser[key] = value; |  | ||||||
| 			} |  | ||||||
| 			return [host, newUser]; |  | ||||||
| 		} |  | ||||||
| 		return [host, user]; |  | ||||||
| 	})); |  | ||||||
| 	miLocalStorage.setItem('account', JSON.stringify($i)); | 	miLocalStorage.setItem('account', JSON.stringify($i)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -223,25 +218,42 @@ export async function openAccountMenu(opts: { | ||||||
| }, ev: MouseEvent) { | }, ev: MouseEvent) { | ||||||
| 	if (!$i) return; | 	if (!$i) return; | ||||||
| 
 | 
 | ||||||
| 	function createItem(host: string, account: Misskey.entities.User): MenuItem { | 	function createItem(host: string, id: Misskey.entities.User['id'], username: Misskey.entities.User['username'], account: Misskey.entities.User | null | undefined, token: string): MenuItem { | ||||||
| 		return { | 		if (account) { | ||||||
| 			type: 'user' as const, | 			return { | ||||||
| 			user: account, | 				type: 'user' as const, | ||||||
| 			active: opts.active != null ? opts.active === account.id : false, | 				user: account, | ||||||
| 			action: async () => { | 				active: opts.active != null ? opts.active === id : false, | ||||||
| 				if (opts.onChoose) { | 				action: async () => { | ||||||
| 					opts.onChoose(account); | 					if (opts.onChoose) { | ||||||
| 				} else { | 						opts.onChoose(account); | ||||||
| 					switchAccount(host, account.id); | 					} else { | ||||||
| 				} | 						switchAccount(host, id); | ||||||
| 			}, | 					} | ||||||
| 		}; | 				}, | ||||||
|  | 			}; | ||||||
|  | 		} else { | ||||||
|  | 			return { | ||||||
|  | 				type: 'button' as const, | ||||||
|  | 				text: username, | ||||||
|  | 				active: opts.active != null ? opts.active === id : false, | ||||||
|  | 				action: async () => { | ||||||
|  | 					if (opts.onChoose) { | ||||||
|  | 						fetchAccount(token, id).then(account => { | ||||||
|  | 							opts.onChoose(account); | ||||||
|  | 						}); | ||||||
|  | 					} else { | ||||||
|  | 						switchAccount(host, id); | ||||||
|  | 					} | ||||||
|  | 				}, | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	const menuItems: MenuItem[] = []; | 	const menuItems: MenuItem[] = []; | ||||||
| 
 | 
 | ||||||
| 	// TODO: $iのホストも比較したいけど通常null
 | 	// TODO: $iのホストも比較したいけど通常null
 | ||||||
| 	const accountItems = (await getAccounts().then(accounts => accounts.filter(x => x.user.id !== $i.id))).map(a => createItem(a.host, a.user)); | 	const accountItems = (await getAccounts().then(accounts => accounts.filter(x => x.id !== $i.id))).map(a => createItem(a.host, a.id, a.username, a.user, a.token)); | ||||||
| 
 | 
 | ||||||
| 	if (opts.withExtraOperation) { | 	if (opts.withExtraOperation) { | ||||||
| 		menuItems.push({ | 		menuItems.push({ | ||||||
|  | @ -254,7 +266,7 @@ export async function openAccountMenu(opts: { | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		if (opts.includeCurrentAccount) { | 		if (opts.includeCurrentAccount) { | ||||||
| 			menuItems.push(createItem(host, $i)); | 			menuItems.push(createItem(host, $i.id, $i.username, $i, $i.token)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		menuItems.push(...accountItems); | 		menuItems.push(...accountItems); | ||||||
|  | @ -290,7 +302,7 @@ export async function openAccountMenu(opts: { | ||||||
| 		}); | 		}); | ||||||
| 	} else { | 	} else { | ||||||
| 		if (opts.includeCurrentAccount) { | 		if (opts.includeCurrentAccount) { | ||||||
| 			menuItems.push(createItem(host, $i)); | 			menuItems.push(createItem(host, $i.id, $i.username, $i, $i.token)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		menuItems.push(...accountItems); | 		menuItems.push(...accountItems); | ||||||
|  |  | ||||||
|  | @ -157,7 +157,7 @@ async function init() { | ||||||
| 
 | 
 | ||||||
| 	const accounts = await getAccounts(); | 	const accounts = await getAccounts(); | ||||||
| 
 | 
 | ||||||
| 	const accountIdsToFetch = accounts.map(a => a.user.id).filter(id => !users.value.has(id)); | 	const accountIdsToFetch = accounts.map(a => a.id).filter(id => !users.value.has(id)); | ||||||
| 
 | 
 | ||||||
| 	if (accountIdsToFetch.length > 0) { | 	if (accountIdsToFetch.length > 0) { | ||||||
| 		const usersRes = await misskeyApi('users/show', { | 		const usersRes = await misskeyApi('users/show', { | ||||||
|  | @ -169,7 +169,7 @@ async function init() { | ||||||
| 
 | 
 | ||||||
| 			users.value.set(user.id, { | 			users.value.set(user.id, { | ||||||
| 				...user, | 				...user, | ||||||
| 				token: accounts.find(a => a.user.id === user.id)!.token, | 				token: accounts.find(a => a.id === user.id)!.token, | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -879,7 +879,7 @@ async function post(ev?: MouseEvent) { | ||||||
| 
 | 
 | ||||||
| 	if (postAccount.value) { | 	if (postAccount.value) { | ||||||
| 		const storedAccounts = await getAccounts(); | 		const storedAccounts = await getAccounts(); | ||||||
| 		token = storedAccounts.find(x => x.user.id === postAccount.value?.id)?.token; | 		token = storedAccounts.find(x => x.id === postAccount.value?.id)?.token; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	posting.value = true; | 	posting.value = true; | ||||||
|  |  | ||||||
|  | @ -32,10 +32,11 @@ export type SoundStore = { | ||||||
| // NOTE: デフォルト値は他の設定の状態に依存してはならない(依存していた場合、ユーザーがその設定項目単体で「初期値にリセット」した場合不具合の原因になる)
 | // NOTE: デフォルト値は他の設定の状態に依存してはならない(依存していた場合、ユーザーがその設定項目単体で「初期値にリセット」した場合不具合の原因になる)
 | ||||||
| 
 | 
 | ||||||
| export const PREF_DEF = { | export const PREF_DEF = { | ||||||
| 	// TODO: 持つのはホストやユーザーID、ユーザー名など最低限にしといて、その他のプロフィール情報はpreferences外で管理した方が綺麗そう
 |  | ||||||
| 	// 現状だと、updateCurrentAccount/updateCurrentAccountPartialが呼ばれるたびに「設定」へのcommitが行われて不自然(明らかに設定の更新とは捉えにくい)だし
 |  | ||||||
| 	accounts: { | 	accounts: { | ||||||
| 		default: [] as [host: string, user: Misskey.entities.User][], | 		default: [] as [host: string, user: { | ||||||
|  | 			id: string; | ||||||
|  | 			username: string; | ||||||
|  | 		}][], | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	pinnedUserLists: { | 	pinnedUserLists: { | ||||||
|  |  | ||||||
|  | @ -108,6 +108,10 @@ export const store = markRaw(new Pizzax('base', { | ||||||
| 		where: 'device', | 		where: 'device', | ||||||
| 		default: {} as Record<string, string>, // host/userId, token
 | 		default: {} as Record<string, string>, // host/userId, token
 | ||||||
| 	}, | 	}, | ||||||
|  | 	accountInfos: { | ||||||
|  | 		where: 'device', | ||||||
|  | 		default: {} as Record<string, Misskey.entities.User>, // host/userId, user
 | ||||||
|  | 	}, | ||||||
| 
 | 
 | ||||||
| 	enablePreferencesAutoCloudBackup: { | 	enablePreferencesAutoCloudBackup: { | ||||||
| 		where: 'device', | 		where: 'device', | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue