Display moved info.

It already fetches the moved to info on regular user fetches, now only the notification of a new "moved to" is missing.

Signed-off-by: cutestnekoaqua <waterdev@galaxycrow.de>
Co-authored-by: Mary Strodl <ipadlover8322@gmail.com>
Signed-off-by: cutestnekoaqua <waterdev@galaxycrow.de>
This commit is contained in:
Cleo 2022-11-30 20:26:13 +01:00 committed by cutestnekoaqua
parent bcce957f86
commit dcda17d6f2
7 changed files with 92 additions and 11 deletions

View File

@ -112,6 +112,7 @@ reactionSettingDescription2: "Ziehe um Anzuordnen, klicke um zu löschen, drück
rememberNoteVisibility: "Notizsichtbarkeit merken"
attachCancel: "Anhang entfernen"
markAsSensitive: "Als NSFW markieren"
accountMoved: "Benutzer hat zu einem anderen Account gewechselt."
unmarkAsSensitive: "Als nicht NSFW markieren"
enterFileName: "Dateinamen eingeben"
mute: "Stummschalten"

View File

@ -149,6 +149,7 @@ addAccount: "Add account"
loginFailed: "Failed to sign in"
showOnRemote: "View on remote instance"
general: "General"
accountMoved: "User has moved to a new account."
wallpaper: "Wallpaper"
setWallpaper: "Set wallpaper"
removeWallpaper: "Remove wallpaper"

View File

@ -149,6 +149,7 @@ addAccount: "アカウントを追加"
loginFailed: "ログインに失敗しました"
showOnRemote: "リモートで表示"
general: "全般"
accountMoved: "このユーザーは新しいアカウントに移行しました"
wallpaper: "壁紙"
setWallpaper: "壁紙を設定"
removeWallpaper: "壁紙を削除"

View File

@ -1,6 +1,6 @@
import { EntityRepository, Repository, In, Not } from 'typeorm';
import {In, Not} from 'typeorm';
import Ajv from 'ajv';
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
import {ILocalUser, IRemoteUser, User} from '@/models/entities/user.js';
import config from '@/config/index.js';
import {Packed} from '@/misc/schema.js';
import {awaitAll, Promiseable} from '@/prelude/await-all.js';
@ -10,7 +10,29 @@ import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
import {Cache} from '@/misc/cache.js';
import {db} from '@/db/postgre.js';
import {Instance} from '../entities/instance.js';
import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index.js';
import {resolveUser} from "@/remote/resolve-user";
import {URL} from "url";
import {
AnnouncementReads,
Announcements,
AntennaNotes,
Blockings,
ChannelFollowings,
DriveFiles,
Followings,
FollowRequests,
Instances,
MessagingMessages,
Mutings,
Notes,
NoteUnreads,
Notifications,
Pages,
UserGroupJoinings,
UserNotePinings,
UserProfiles,
UserSecurityKeys
} from '../index.js';
const userInstanceCache = new Cache<Instance | null>(1000 * 60 * 60 * 3);
@ -156,6 +178,23 @@ export const UserRepository = db.getRepository(User).extend({
return count > 0;
},
async userFromURI(uri: string): Promise<User | null> {
if (uri.startsWith(config.url + '/')) {
const id = uri.split('/').pop();
if (id == undefined) return null;
return await resolveUser(id, null);
}
let url = new URL(uri);
let userTag = url.pathname;
if (userTag.startsWith("@")) {
userTag = userTag.substring(1);
}
return await resolveUser(userTag, url.host);
},
async getHasUnreadAntenna(userId: User['id']): Promise<boolean> {
const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
@ -320,6 +359,8 @@ export const UserRepository = db.getRepository(User).extend({
...(opts.detail ? {
url: profile!.url,
uri: user.uri,
movedTo: user.movedToUri ? await this.userFromURI(user.movedToUri) : null,
alsoKnownAs: user.alsoKnownAs,
createdAt: user.createdAt.toISOString(),
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,

View File

@ -96,6 +96,16 @@ export const packedUserDetailedNotMeOnlySchema = {
format: 'uri',
nullable: true, optional: false,
},
movedTo: {
type: 'string',
format: 'uri',
nullable: true, optional: false,
},
alsoKnownAs: {
type: 'array',
format: 'uri',
nullable: true, optional: false,
},
createdAt: {
type: 'string',
nullable: false, optional: false,

View File

@ -0,0 +1,25 @@
<template>
<div class="mkmoved _block"><i class="fas fa-info-circle" style="margin-right: 8px;"></i>{{ i18n.ts.accountMoved }}<a class="link" :href="href">{{ acct }}</a></div>
</template>
<script lang="ts" setup>
import { i18n } from '@/i18n';
import { computed } from 'vue';
const props = defineProps<{
acct: string;
}>();
const href = $computed(() => `/${props.acct}`);
</script>
<style lang="scss" scoped>
.mkmoved {
font-size: 0.8em;
padding: 16px;
background: var(--infoBg);
color: var(--infoFg);
> .link {
margin-left: 4px;
color: var(--accent);
}
}
</style>

View File

@ -8,6 +8,7 @@
<div class="profile">
<MkRemoteCaution v-if="user.host != null" :href="user.url" class="warn"/>
<MkMoved v-if="user.movedTo" :acct="user.movedTo" />
<div :key="user.id" class="_block main">
<div class="banner-container" :style="style">
@ -119,6 +120,7 @@ import MkFolder from '@/components/MkFolder.vue';
import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
import MkTab from '@/components/MkTab.vue';
import MkInfo from '@/components/MkInfo.vue';
import MkMoved from '@/components/MkMoved.vue';
import { getScrollPosition } from '@/scripts/scroll';
import { getUserMenu } from '@/scripts/get-user-menu';
import number from '@/filters/number';