From 8a5daa866cc8be53fe244ced1ccf3f4eb41f24a9 Mon Sep 17 00:00:00 2001 From: xeltica Date: Sat, 9 Oct 2021 02:11:00 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=9E=E3=83=AB=E3=83=81=E3=82=A2=E3=82=AB?= =?UTF-8?q?=E3=82=A6=E3=83=B3=E3=83=88=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 +- src/backend/const.ts | 2 +- src/backend/views/frontend.pug | 9 +++- src/frontend/components/AccountsPage.tsx | 67 ++++++++++++++++++++++++ src/frontend/components/LoginForm.tsx | 2 +- src/frontend/const.ts | 1 + src/frontend/langs/ja-JP.json | 6 +++ src/frontend/pages/index.session.tsx | 26 ++++++++- src/frontend/pages/index.welcome.tsx | 2 +- src/frontend/store/slices/screen.ts | 14 ++++- src/frontend/style.scss | 5 ++ 11 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 src/frontend/components/AccountsPage.tsx diff --git a/package.json b/package.json index 347a4fc..f935433 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "misshaialert", - "version": "1.5.1", + "name": "misskey-tools", + "version": "2.0.0", "description": "", "main": "built/app.js", "author": "Xeltica", diff --git a/src/backend/const.ts b/src/backend/const.ts index 6b172b1..3674531 100644 --- a/src/backend/const.ts +++ b/src/backend/const.ts @@ -1,5 +1,5 @@ export default { - version: '1.5.1', + version: '2.0.0', changelog: [ 'インスタンスの接続エラーにより後続処理が行えなくなる重大な不具合を修正', '全員分の算出が終わるまで、ランキングを非表示に', diff --git a/src/backend/views/frontend.pug b/src/backend/views/frontend.pug index 44d0f42..41e9108 100644 --- a/src/backend/views/frontend.pug +++ b/src/backend/views/frontend.pug @@ -31,7 +31,14 @@ html if token script. - localStorage.setItem('token', '#{token}'); + const token = '#{token}'; + const previousToken = localStorage.getItem('token'); + const accounts = JSON.parse(localStorage.getItem('accounts') && '[]'); + if (previousToken && !accounts.includes(previousToken)) { + accounts.push(previousToken); + } + localStorage.setItem('accounts', JSON.stringify(accounts)); + localStorage.setItem('token', token); history.replaceState(null, null, '/'); if error diff --git a/src/frontend/components/AccountsPage.tsx b/src/frontend/components/AccountsPage.tsx new file mode 100644 index 0000000..ccd9ff3 --- /dev/null +++ b/src/frontend/components/AccountsPage.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; +import { LOCALSTORAGE_KEY_ACCOUNTS, LOCALSTORAGE_KEY_TOKEN } from '../const'; +import { useGetSessionQuery } from '../services/session'; +import { useSelector } from '../store'; +import { setAccounts } from '../store/slices/screen'; +import { LoginForm } from './LoginForm'; +import { Skeleton } from './Skeleton'; + +export const AccountsPage: React.VFC = () => { + const {data} = useGetSessionQuery(undefined); + const {t} = useTranslation(); + const dispatch = useDispatch(); + + const {accounts, accountTokens} = useSelector(state => state.screen); + + const switchAccount = (token: string) => { + const newAccounts = accountTokens.filter(a => a !== token); + newAccounts.push(localStorage.getItem(LOCALSTORAGE_KEY_TOKEN) ?? ''); + localStorage.setItem(LOCALSTORAGE_KEY_ACCOUNTS, JSON.stringify(newAccounts)); + localStorage.setItem(LOCALSTORAGE_KEY_TOKEN, token); + location.reload(); + }; + + return !data ? ( +
+ + + +
+ ) : ( +
+
+
+

{t('_accounts.currentAccount')}

+

@{data.username}@{data.host}

+
+
+
+

{t('_accounts.switchAccount')}

+
+ { + accounts.length === accountTokens.length ? ( + accounts.map(account => ( + + + )) + ) : ( +
...
+ ) + } +
+ +
+
+ ); +}; diff --git a/src/frontend/components/LoginForm.tsx b/src/frontend/components/LoginForm.tsx index 5638e8c..7a3aed2 100644 --- a/src/frontend/components/LoginForm.tsx +++ b/src/frontend/components/LoginForm.tsx @@ -10,7 +10,7 @@ export const LoginForm: React.VFC = () => {
{t('instanceUrl')}
-
+
{ + return fetch(`${API_ENDPOINT}session`, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }).then(r => r.json()).then(r => r as IUser); +}; export const IndexSessionPage: React.VFC = () => { const [selectedTab, setSelectedTab] = useState(0); const {t, i18n} = useTranslation(); + const dispatch = useDispatch(); + + useEffect(() => { + const accounts = JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY_ACCOUNTS) || '[]') as string[]; + Promise.all(accounts.map(getSession)).then(a => dispatch(setAccounts(a))); + }, [dispatch]); const items = useMemo(() => ([ { label: t('_nav.misshai') }, + { label: t('_nav.accounts') }, { label: t('_nav.settings') }, ]), [i18n.language]); const component = useMemo(() => { switch (selectedTab) { case 0: return ; - case 1: return ; + case 1: return ; + case 2: return ; default: return null; } }, [selectedTab]); diff --git a/src/frontend/pages/index.welcome.tsx b/src/frontend/pages/index.welcome.tsx index aa0a739..2fcdeb5 100644 --- a/src/frontend/pages/index.welcome.tsx +++ b/src/frontend/pages/index.welcome.tsx @@ -35,7 +35,7 @@ export const IndexWelcomePage: React.VFC = () => {

{t('_welcome.misshaiAlertTitle')}

{t('_welcome.misshaiAlertDescription')}

-
+
{example}
diff --git a/src/frontend/store/slices/screen.ts b/src/frontend/store/slices/screen.ts index ec37d69..ed2db3d 100644 --- a/src/frontend/store/slices/screen.ts +++ b/src/frontend/store/slices/screen.ts @@ -1,7 +1,8 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import i18n from 'i18next'; +import { IUser } from '../../../common/types/user'; -import { LOCALSTORAGE_KEY_LANG, LOCALSTORAGE_KEY_THEME } from '../../const'; +import { LOCALSTORAGE_KEY_ACCOUNTS, LOCALSTORAGE_KEY_LANG, LOCALSTORAGE_KEY_THEME } from '../../const'; import { Theme } from '../../misc/theme'; import { Modal } from '../../modal/modal'; @@ -10,6 +11,8 @@ interface ScreenState { modalShown: boolean; theme: Theme; language: string; + accounts: IUser[]; + accountTokens: string[]; } const initialState: ScreenState = { @@ -17,6 +20,8 @@ const initialState: ScreenState = { modalShown: false, theme: localStorage[LOCALSTORAGE_KEY_THEME] ?? 'system', language: localStorage[LOCALSTORAGE_KEY_LANG] ?? i18n.language ?? 'ja_JP', + accounts: [], + accountTokens: JSON.parse(localStorage.getItem(LOCALSTORAGE_KEY_ACCOUNTS) || '[]') as string[], }; export const screenSlice = createSlice({ @@ -40,9 +45,14 @@ export const screenSlice = createSlice({ localStorage[LOCALSTORAGE_KEY_LANG] = action.payload; i18n.changeLanguage(action.payload); }, + setAccounts: (state, action: PayloadAction) => { + state.accounts = action.payload; + state.accountTokens = action.payload.map(a => a.misshaiToken); + localStorage[LOCALSTORAGE_KEY_ACCOUNTS] = JSON.stringify(state.accountTokens); + }, }, }); -export const { showModal, hideModal, changeTheme, changeLang } = screenSlice.actions; +export const { showModal, hideModal, changeTheme, changeLang, setAccounts } = screenSlice.actions; export default screenSlice.reducer; diff --git a/src/frontend/style.scss b/src/frontend/style.scss index 8b0efd5..9fa9156 100644 --- a/src/frontend/style.scss +++ b/src/frontend/style.scss @@ -92,3 +92,8 @@ small { padding: calc(var(--margin) / 2); background: var(--panel); } + +.login-form { + background: var(--panel); + border-radius: var(--radius); +}