Merge remote-tracking branch 'misskey-original/develop' into develop

# Conflicts:
#	package.json
#	packages/frontend/src/components/MkNotifications.vue
#	packages/frontend/src/components/MkPostForm.vue
#	packages/frontend/src/components/MkTimeline.vue
#	packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
#	packages/frontend/src/pages/user/home.vue
#	packages/frontend/src/ui/_common_/navbar.vue
#	packages/frontend/src/ui/_common_/stream-indicator.vue
This commit is contained in:
mattyatea 2023-11-15 13:32:09 +09:00
commit d439dd66f9
68 changed files with 2145 additions and 1290 deletions

View file

@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<option value="publishing">{{ i18n.ts.publishing }}</option>
<option value="suspended">{{ i18n.ts.suspended }}</option>
<option value="blocked">{{ i18n.ts.blocked }}</option>
<option value="silenced">{{ i18n.ts.silence }}</option>
<option value="notResponding">{{ i18n.ts.notResponding }}</option>
</MkSelect>
<MkSelect v-model="sort">
@ -83,6 +84,7 @@ const pagination = {
state === 'publishing' ? { publishing: true } :
state === 'suspended' ? { suspended: true } :
state === 'blocked' ? { blocked: true } :
state === 'silenced' ? { silenced: true } :
state === 'notResponding' ? { notResponding: true } :
{}),
})),
@ -91,6 +93,7 @@ const pagination = {
function getStatus(instance) {
if (instance.isSuspended) return 'Suspended';
if (instance.isBlocked) return 'Blocked';
if (instance.isSilenced) return 'Silenced';
if (instance.isNotResponding) return 'Error';
return 'Alive';
}

View file

@ -34,7 +34,7 @@ import MkSuperMenu from '@/components/MkSuperMenu.vue';
import MkInfo from '@/components/MkInfo.vue';
import { instance } from '@/instance.js';
import * as os from '@/os.js';
import { lookupUser } from '@/scripts/lookup-user.js';
import { lookupUser, lookupUserByEmail } from '@/scripts/lookup-user.js';
import { useRouter } from '@/router.js';
import { definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
import {bannerDark, bannerLight, defaultStore, iconDark, iconLight} from "@/store.js";
@ -278,7 +278,7 @@ provideMetadataReceiver((info) => {
}
});
const invite = () => {
function invite() {
os.api('admin/invite/create').then(x => {
os.alert({
type: 'info',
@ -290,15 +290,21 @@ const invite = () => {
text: err,
});
});
};
}
const lookup = (ev) => {
function lookup(ev: MouseEvent) {
os.popupMenu([{
text: i18n.ts.user,
icon: 'ti ti-user',
action: () => {
lookupUser();
},
}, {
text: `${i18n.ts.user} (${i18n.ts.email})`,
icon: 'ti ti-user',
action: () => {
lookupUserByEmail();
},
}, {
text: i18n.ts.note,
icon: 'ti ti-pencil',
@ -318,7 +324,7 @@ const lookup = (ev) => {
alert('TODO');
},
}], ev.currentTarget ?? ev.target);
};
}
const headerActions = $computed(() => []);

View file

@ -18,11 +18,19 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer v-else-if="tab === 'users'" :contentMax="1200">
<div class="_gaps_s">
<div v-if="role">{{ role.description }}</div>
<MkUserList :pagination="users" :extractor="(item) => item.user"/>
<MkUserList v-if="visiable" :pagination="users" :extractor="(item) => item.user"/>
<div v-else-if="!visiable" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>
</MkSpacer>
<MkSpacer v-else-if="tab === 'timeline'" :contentMax="700">
<MkTimeline ref="timeline" src="role" :role="props.role"/>
<MkTimeline v-if="visiable" ref="timeline" src="role" :role="props.role"/>
<div v-else-if="!visiable" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</MkSpacer>
</MkStickyContainer>
</template>
@ -35,7 +43,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import { i18n } from '@/i18n.js';
import MkTimeline from '@/components/MkTimeline.vue';
import { instanceName } from '@/config.js';
import { serverErrorImageUrl } from '@/instance.js';
import { serverErrorImageUrl, infoImageUrl } from '@/instance.js';
const props = withDefaults(defineProps<{
role: string;
@ -47,6 +55,7 @@ const props = withDefaults(defineProps<{
let tab = $ref(props.initialTab);
let role = $ref();
let error = $ref();
let visiable = $ref(false);
watch(() => props.role, () => {
os.api('roles/show', {
@ -54,6 +63,7 @@ watch(() => props.role, () => {
}).then(res => {
role = res;
document.title = `${role?.name} | ${instanceName}`;
visiable = res.isExplorable && res.isPublic;
}).catch((err) => {
if (err.code === 'NO_SUCH_ROLE') {
error = i18n.ts.noRole;

View file

@ -149,12 +149,13 @@ async function reloadAsk() {
}
async function updateRepliesAll(withReplies: boolean) {
const { canceled } = os.confirm({
const { canceled } = await os.confirm({
type: 'warning',
text: withReplies ? i18n.ts.confirmShowRepliesAll : i18n.ts.confirmHideRepliesAll,
});
if (canceled) return;
await os.api('following/update-all', { withReplies });
os.api('following/update-all', { withReplies });
}
watch([

View file

@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
class="ti ti-shield"></i></span>
<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ti ti-lock"></i></span>
<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ti ti-robot"></i></span>
<button v-if="!isEditingMemo && !memoDraft" class="_button add-note-button" @click="showMemoTextarea">
<button v-if="$i && !isEditingMemo && !memoDraft" class="_button add-note-button" @click="showMemoTextarea">
<i class="ti ti-edit"/> {{ i18n.ts.addMemo }}
</button>
</div>