enhance(frontend): improve accounts management
This commit is contained in:
parent
44073736de
commit
8c9ec5827f
137 changed files with 640 additions and 622 deletions
|
|
@ -117,7 +117,7 @@ import MkFolder from '@/components/MkFolder.vue';
|
|||
import MkInfo from '@/components/MkInfo.vue';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
import { confetti } from '@/utility/confetti.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
|
|
|
|||
|
|
@ -92,8 +92,9 @@ import FormSection from '@/components/form/section.vue';
|
|||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { signinRequired, updateAccountPartial } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { updateCurrentAccountPartial } from '@/accounts.js';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ async function unregisterTOTP(): Promise<void> {
|
|||
password: auth.result.password,
|
||||
token: auth.result.token,
|
||||
}).then(res => {
|
||||
updateAccountPartial({
|
||||
updateCurrentAccountPartial({
|
||||
twoFactorEnabled: false,
|
||||
});
|
||||
}).catch(error => {
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ import { misskeyApi } from '@/utility/misskey-api.js';
|
|||
import { selectFile } from '@/utility/select-file.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { $i } from '@/i.js';
|
||||
import MkFeatureBanner from '@/components/MkFeatureBanner.vue';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -4,80 +4,51 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
-->
|
||||
|
||||
<template>
|
||||
<div class="">
|
||||
<FormSuspense :p="init">
|
||||
<div class="_gaps">
|
||||
<div class="_buttons">
|
||||
<MkButton primary @click="addAccount"><i class="ti ti-plus"></i> {{ i18n.ts.addAccount }}</MkButton>
|
||||
<MkButton @click="init"><i class="ti ti-refresh"></i> {{ i18n.ts.reloadAccountsList }}</MkButton>
|
||||
</div>
|
||||
|
||||
<template v-for="[id, user] in accounts">
|
||||
<MkUserCardMini v-if="user != null" :key="user.id" :user="user" :class="$style.user" @click.prevent="menu(user, $event)"/>
|
||||
<button v-else v-panel class="_button" :class="$style.unknownUser" @click="menu(id, $event)">
|
||||
<div :class="$style.unknownUserAvatarMock"><i class="ti ti-user-question"></i></div>
|
||||
<div>
|
||||
<div :class="$style.unknownUserTitle">{{ i18n.ts.unknown }}</div>
|
||||
<div :class="$style.unknownUserSub">ID: <span class="_monospace">{{ id }}</span></div>
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
<SearchMarker path="/settings/accounts" :label="i18n.ts.accounts" :keywords="['accounts']" icon="ti ti-users">
|
||||
<div class="_gaps">
|
||||
<div class="_buttons">
|
||||
<MkButton primary @click="addAccount"><i class="ti ti-plus"></i> {{ i18n.ts.addAccount }}</MkButton>
|
||||
<!--<MkButton @click="refreshAllAccounts"><i class="ti ti-refresh"></i></MkButton>-->
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</div>
|
||||
|
||||
<MkUserCardMini v-for="x in accounts" :key="x[0] + x[1].id" :user="x[1]" :class="$style.user" @click.prevent="menu(x[0], x[1], $event)"/>
|
||||
</div>
|
||||
</SearchMarker>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import type { MenuItem } from '@/types/menu.js';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { getAccounts, removeAccount as _removeAccount, login, $i, getAccountWithSigninDialog, getAccountWithSignupDialog } from '@/account.js';
|
||||
import { $i } from '@/i.js';
|
||||
import { switchAccount, removeAccount, login, getAccountWithSigninDialog, getAccountWithSignupDialog } from '@/accounts.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import MkUserCardMini from '@/components/MkUserCardMini.vue';
|
||||
import type { MenuItem } from '@/types/menu.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const storedAccounts = ref<{ id: string, token: string }[] | null>(null);
|
||||
const accounts = ref(new Map<string, Misskey.entities.UserDetailed | null>());
|
||||
const accounts = prefer.r.accounts;
|
||||
|
||||
const init = async () => {
|
||||
getAccounts().then(accounts => {
|
||||
storedAccounts.value = accounts.filter(x => x.id !== $i!.id);
|
||||
function refreshAllAccounts() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
return misskeyApi('users/show', {
|
||||
userIds: storedAccounts.value.map(x => x.id),
|
||||
});
|
||||
}).then(response => {
|
||||
if (storedAccounts.value == null) return;
|
||||
accounts.value = new Map(storedAccounts.value.map(x => [x.id, response.find((y: Misskey.entities.UserDetailed) => y.id === x.id) ?? null]));
|
||||
});
|
||||
};
|
||||
|
||||
function menu(account: Misskey.entities.UserDetailed | string, ev: MouseEvent) {
|
||||
function menu(host: string, account: Misskey.entities.UserDetailed, ev: MouseEvent) {
|
||||
let menu: MenuItem[];
|
||||
|
||||
if (typeof account === 'string') {
|
||||
menu = [{
|
||||
text: i18n.ts.logout,
|
||||
icon: 'ti ti-trash',
|
||||
danger: true,
|
||||
action: () => removeAccount(account),
|
||||
}];
|
||||
} else {
|
||||
menu = [{
|
||||
text: i18n.ts.switch,
|
||||
icon: 'ti ti-switch-horizontal',
|
||||
action: () => switchAccount(account.id),
|
||||
}, {
|
||||
text: i18n.ts.logout,
|
||||
icon: 'ti ti-trash',
|
||||
danger: true,
|
||||
action: () => removeAccount(account.id),
|
||||
}];
|
||||
}
|
||||
menu = [{
|
||||
text: i18n.ts.switch,
|
||||
icon: 'ti ti-switch-horizontal',
|
||||
action: () => switchAccount(host, account.id),
|
||||
}, {
|
||||
text: i18n.ts.logout,
|
||||
icon: 'ti ti-trash',
|
||||
danger: true,
|
||||
action: () => removeAccount(host, account.id),
|
||||
}];
|
||||
|
||||
os.popupMenu(menu, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
|
@ -92,16 +63,10 @@ function addAccount(ev: MouseEvent) {
|
|||
}], ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
async function removeAccount(id: string) {
|
||||
await _removeAccount(id);
|
||||
accounts.value.delete(id);
|
||||
}
|
||||
|
||||
function addExistingAccount() {
|
||||
getAccountWithSigninDialog().then((res) => {
|
||||
if (res != null) {
|
||||
os.success();
|
||||
init();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -109,21 +74,11 @@ function addExistingAccount() {
|
|||
function createAccount() {
|
||||
getAccountWithSignupDialog().then((res) => {
|
||||
if (res != null) {
|
||||
switchAccountWithToken(res.token);
|
||||
login(res.token);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function switchAccount(id: string) {
|
||||
const fetchedAccounts = await getAccounts();
|
||||
const token = fetchedAccounts.find(x => x.id === id)!.token;
|
||||
switchAccountWithToken(token);
|
||||
}
|
||||
|
||||
function switchAccountWithToken(token: string) {
|
||||
login(token);
|
||||
}
|
||||
|
||||
const headerActions = computed(() => []);
|
||||
|
||||
const headerTabs = computed(() => []);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import MkModalWindow from '@/components/MkModalWindow.vue';
|
|||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkRange from '@/components/MkRange.vue';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ import MkButton from '@/components/MkButton.vue';
|
|||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
import { definePage } from '@/page.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ import bytes from '@/filters/bytes.js';
|
|||
import MkChart from '@/components/MkChart.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import MkPreferenceContainer from '@/components/MkPreferenceContainer.vue';
|
||||
import MkFeatureBanner from '@/components/MkFeatureBanner.vue';
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ import MkSwitch from '@/components/MkSwitch.vue';
|
|||
import MkDisableSection from '@/components/MkDisableSection.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { instance } from '@/instance.js';
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import type { SuperMenuDef } from '@/components/MkSuperMenu.vue';
|
|||
import { i18n } from '@/i18n.js';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
import MkSuperMenu from '@/components/MkSuperMenu.vue';
|
||||
import { signout, $i } from '@/account.js';
|
||||
import { $i } from '@/i.js';
|
||||
import { clearCache } from '@/utility/clear-cache.js';
|
||||
import { instance } from '@/instance.js';
|
||||
import { definePage, provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
|
||||
|
|
@ -47,6 +47,7 @@ import { useRouter } from '@/router/supplier.js';
|
|||
import { searchIndexes } from '@/utility/autogen/settings-search-index.js';
|
||||
import { enableAutoBackup, getPreferencesProfileMenu } from '@/preferences/utility.js';
|
||||
import { store } from '@/store.js';
|
||||
import { signout } from '@/signout.js';
|
||||
|
||||
const SETTING_INDEX = searchIndexes; // TODO: lazy load
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ import MkUserInfo from '@/components/MkUserInfo.vue';
|
|||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { unisonReload } from '@/utility/unison-reload.js';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { ref, watch } from 'vue';
|
|||
import MkTextarea from '@/components/MkTextarea.vue';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ import { definePage } from '@/page.js';
|
|||
import MkUserCardMini from '@/components/MkUserCardMini.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { instance, infoImageUrl } from '@/instance.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ import FormSection from '@/components/form/section.vue';
|
|||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
|
|
|
|||
|
|
@ -127,13 +127,14 @@ import MkKeyValue from '@/components/MkKeyValue.vue';
|
|||
import MkButton from '@/components/MkButton.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { signout, signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { reloadAsk } from '@/utility/reload-ask.js';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import MkRolePreview from '@/components/MkRolePreview.vue';
|
||||
import { signout } from '@/signout.js';
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ import MkFolder from '@/components/MkFolder.vue';
|
|||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { instance } from '@/instance.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import FormSlot from '@/components/form/slot.vue';
|
||||
import { formatDateTimeString } from '@/utility/format-time-string.js';
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ import FormSlot from '@/components/form/slot.vue';
|
|||
import { selectFile } from '@/utility/select-file.js';
|
||||
import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { signinRequired } from '@/account.js';
|
||||
import { signinRequired } from '@/i.js';
|
||||
import { langmap } from '@/utility/langmap.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue