forked from FoundKeyGang/FoundKey
Compare commits
9 commits
5d6cceda49
...
16902a26a3
Author | SHA1 | Date | |
---|---|---|---|
16902a26a3 | |||
1ffa4b08e0 | |||
c9d395961e | |||
3a7e8cfe50 | |||
b8796cb1fa | |||
68bc2e314b | |||
fff93c6965 | |||
7c89e99243 | |||
6ed13ea9a7 |
13 changed files with 44 additions and 37 deletions
|
@ -5,8 +5,8 @@ export class registryRemoveDomain1675375940759 {
|
||||||
await queryRunner.query(`DROP INDEX "public"."IDX_0a72bdfcdb97c0eca11fe7ecad"`);
|
await queryRunner.query(`DROP INDEX "public"."IDX_0a72bdfcdb97c0eca11fe7ecad"`);
|
||||||
await queryRunner.query(`ALTER TABLE "registry_item" DROP COLUMN "domain"`);
|
await queryRunner.query(`ALTER TABLE "registry_item" DROP COLUMN "domain"`);
|
||||||
await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "key" TYPE text USING "key"::text`);
|
await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "key" TYPE text USING "key"::text`);
|
||||||
// delete existing duplicated entries, keeping the latest updated one
|
// delete existing duplicated entries, keeping the latest created one
|
||||||
await queryRunner.query(`DELETE FROM "registry_item" AS "a" WHERE "updatedAt" != (SELECT MAX("updatedAt") FROM "registry_item" AS "b" WHERE "a"."userId" = "b"."userId" AND "a"."key" = "b"."key" AND "a"."scope" = "b"."scope" GROUP BY "userId", "key", "scope")`);
|
await queryRunner.query(`DELETE FROM "registry_item" AS "a" WHERE "id" != (SELECT MAX("id") FROM "registry_item" AS "b" WHERE "a"."userId" = "b"."userId" AND "a"."key" = "b"."key" AND "a"."scope" = "b"."scope" GROUP BY "userId", "key", "scope")`);
|
||||||
await queryRunner.query(`ALTER TABLE "registry_item" ADD CONSTRAINT "UQ_b8d6509f847331273ab99daccc7" UNIQUE ("userId", "key", "scope")`);
|
await queryRunner.query(`ALTER TABLE "registry_item" ADD CONSTRAINT "UQ_b8d6509f847331273ab99daccc7" UNIQUE ("userId", "key", "scope")`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,16 +270,14 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
|
|
||||||
const followingCount = profile == null ? null :
|
const followingCount = profile == null ? null :
|
||||||
(profile.ffVisibility === 'public') || isMe ? user.followingCount :
|
(profile.ffVisibility === 'public') || isMe ? user.followingCount :
|
||||||
(profile.ffVisibility === 'followers') && (relation && relation.isFollowing) ? user.followingCount :
|
(profile.ffVisibility === 'followers') && relation?.isFollowing ? user.followingCount :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
const followersCount = profile == null ? null :
|
const followersCount = profile == null ? null :
|
||||||
(profile.ffVisibility === 'public') || isMe ? user.followersCount :
|
(profile.ffVisibility === 'public') || isMe ? user.followersCount :
|
||||||
(profile.ffVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount :
|
(profile.ffVisibility === 'followers') && relation?.isFollowing ? user.followersCount :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
const falsy = opts.detail ? false : undefined;
|
|
||||||
|
|
||||||
const packed = {
|
const packed = {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
|
@ -287,10 +285,10 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
host: user.host,
|
host: user.host,
|
||||||
avatarUrl: this.getAvatarUrlSync(user),
|
avatarUrl: this.getAvatarUrlSync(user),
|
||||||
avatarBlurhash: user.avatar?.blurhash || null,
|
avatarBlurhash: user.avatar?.blurhash || null,
|
||||||
isAdmin: user.isAdmin || falsy,
|
isAdmin: user.isAdmin,
|
||||||
isModerator: user.isModerator || falsy,
|
isModerator: user.isModerator,
|
||||||
isBot: user.isBot || falsy,
|
isBot: user.isBot,
|
||||||
isCat: user.isCat || falsy,
|
isCat: user.isCat,
|
||||||
instance: !user.host ? undefined : userInstanceCache.fetch(user.host)
|
instance: !user.host ? undefined : userInstanceCache.fetch(user.host)
|
||||||
.then(instance => !instance ? undefined : {
|
.then(instance => !instance ? undefined : {
|
||||||
name: instance.name,
|
name: instance.name,
|
||||||
|
@ -312,8 +310,8 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
bannerUrl: user.banner ? DriveFiles.getPublicUrl(user.banner, false) : null,
|
bannerUrl: user.banner ? DriveFiles.getPublicUrl(user.banner, false) : null,
|
||||||
bannerBlurhash: user.banner?.blurhash || null,
|
bannerBlurhash: user.banner?.blurhash || null,
|
||||||
isLocked: user.isLocked,
|
isLocked: user.isLocked,
|
||||||
isSilenced: user.isSilenced || falsy,
|
isSilenced: user.isSilenced,
|
||||||
isSuspended: user.isSuspended || falsy,
|
isSuspended: user.isSuspended,
|
||||||
description: profile!.description,
|
description: profile!.description,
|
||||||
location: profile!.location,
|
location: profile!.location,
|
||||||
birthday: profile!.birthday,
|
birthday: profile!.birthday,
|
||||||
|
@ -369,7 +367,7 @@ export const UserRepository = db.getRepository(User).extend({
|
||||||
mutedInstances: profile!.mutedInstances,
|
mutedInstances: profile!.mutedInstances,
|
||||||
mutingNotificationTypes: profile!.mutingNotificationTypes,
|
mutingNotificationTypes: profile!.mutingNotificationTypes,
|
||||||
emailNotificationTypes: profile!.emailNotificationTypes,
|
emailNotificationTypes: profile!.emailNotificationTypes,
|
||||||
showTimelineReplies: user.showTimelineReplies || falsy,
|
showTimelineReplies: user.showTimelineReplies,
|
||||||
federateBlocks: user!.federateBlocks,
|
federateBlocks: user!.federateBlocks,
|
||||||
} : {}),
|
} : {}),
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default async (actor: CacheableRemoteUser, activity: ILike) => {
|
||||||
|
|
||||||
await extractEmojis(activity.tag || [], actor.host).catch(() => null);
|
await extractEmojis(activity.tag || [], actor.host).catch(() => null);
|
||||||
|
|
||||||
return await createReaction(actor, note, activity._misskey_reaction || activity.content || activity.name).catch(e => {
|
return await createReaction(actor, note, activity.content || activity.name).catch(e => {
|
||||||
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') {
|
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') {
|
||||||
return 'skip: already reacted';
|
return 'skip: already reacted';
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -207,8 +207,6 @@ export async function createNote(value: string | IObject, resolver: Resolver, si
|
||||||
let text: string | null = null;
|
let text: string | null = null;
|
||||||
if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
|
if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
|
||||||
text = note.source.content;
|
text = note.source.content;
|
||||||
} else if (typeof note._misskey_content !== 'undefined') {
|
|
||||||
text = note._misskey_content;
|
|
||||||
} else if (typeof note.content === 'string') {
|
} else if (typeof note.content === 'string') {
|
||||||
text = fromHtml(note.content, quote?.uri);
|
text = fromHtml(note.content, quote?.uri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ export async function extractPollFromQuestion(source: string | IObject, resolver
|
||||||
.map(x => x.name!);
|
.map(x => x.name!);
|
||||||
|
|
||||||
const votes = question[multiple ? 'anyOf' : 'oneOf']!
|
const votes = question[multiple ? 'anyOf' : 'oneOf']!
|
||||||
.map(x => x.replies && x.replies.totalItems || x._misskey_votes || 0);
|
.map(x => x.replies && x.replies.totalItems || 0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
choices,
|
choices,
|
||||||
|
|
|
@ -35,10 +35,7 @@ export const renderActivity = (x: any): IActivity | null => {
|
||||||
value: 'schema:value',
|
value: 'schema:value',
|
||||||
// Misskey
|
// Misskey
|
||||||
misskey: 'https://misskey-hub.net/ns#',
|
misskey: 'https://misskey-hub.net/ns#',
|
||||||
'_misskey_content': 'misskey:_misskey_content',
|
|
||||||
'_misskey_quote': 'misskey:_misskey_quote',
|
'_misskey_quote': 'misskey:_misskey_quote',
|
||||||
'_misskey_reaction': 'misskey:_misskey_reaction',
|
|
||||||
'_misskey_votes': 'misskey:_misskey_votes',
|
|
||||||
'_misskey_talk': 'misskey:_misskey_talk',
|
'_misskey_talk': 'misskey:_misskey_talk',
|
||||||
'isCat': 'misskey:isCat',
|
'isCat': 'misskey:isCat',
|
||||||
// vcard
|
// vcard
|
||||||
|
|
|
@ -13,10 +13,7 @@ export const renderLike = async (noteReaction: NoteReaction, note: Note) => {
|
||||||
id: `${config.url}/likes/${noteReaction.id}`,
|
id: `${config.url}/likes/${noteReaction.id}`,
|
||||||
actor: `${config.url}/users/${noteReaction.userId}`,
|
actor: `${config.url}/users/${noteReaction.userId}`,
|
||||||
object: note.uri ? note.uri : `${config.url}/notes/${noteReaction.noteId}`,
|
object: note.uri ? note.uri : `${config.url}/notes/${noteReaction.noteId}`,
|
||||||
... (reaction !== '\u2b50' ? {
|
content: reaction,
|
||||||
content: reaction,
|
|
||||||
_misskey_reaction: reaction,
|
|
||||||
} : {}),
|
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
if (reaction.startsWith(':')) {
|
if (reaction.startsWith(':')) {
|
||||||
|
|
|
@ -145,7 +145,6 @@ export default async function renderNote(note: Note, dive = true, isTalk = false
|
||||||
attributedTo,
|
attributedTo,
|
||||||
summary,
|
summary,
|
||||||
content,
|
content,
|
||||||
_misskey_content: text,
|
|
||||||
source: {
|
source: {
|
||||||
content: text,
|
content: text,
|
||||||
mediaType: 'text/x.misskeymarkdown',
|
mediaType: 'text/x.misskeymarkdown',
|
||||||
|
|
|
@ -11,7 +11,6 @@ export default async function renderQuestion(user: { id: User['id'] }, note: Not
|
||||||
content: note.text || '',
|
content: note.text || '',
|
||||||
[poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({
|
[poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({
|
||||||
name: text,
|
name: text,
|
||||||
_misskey_votes: poll.votes[i],
|
|
||||||
replies: {
|
replies: {
|
||||||
type: 'Collection',
|
type: 'Collection',
|
||||||
totalItems: poll.votes[i],
|
totalItems: poll.votes[i],
|
||||||
|
|
|
@ -171,7 +171,6 @@ export const isQuestion = (object: IObject): object is IQuestion =>
|
||||||
interface IQuestionChoice {
|
interface IQuestionChoice {
|
||||||
name?: string;
|
name?: string;
|
||||||
replies?: ICollection;
|
replies?: ICollection;
|
||||||
_misskey_votes?: number;
|
|
||||||
}
|
}
|
||||||
export interface ITombstone extends IObject {
|
export interface ITombstone extends IObject {
|
||||||
type: 'Tombstone';
|
type: 'Tombstone';
|
||||||
|
@ -282,7 +281,7 @@ export interface IRemove extends IActivity {
|
||||||
|
|
||||||
export interface ILike extends IActivity {
|
export interface ILike extends IActivity {
|
||||||
type: 'Like' | 'EmojiReaction' | 'EmojiReact';
|
type: 'Like' | 'EmojiReaction' | 'EmojiReact';
|
||||||
_misskey_reaction?: string;
|
content?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAnnounce extends IActivity {
|
export interface IAnnounce extends IActivity {
|
||||||
|
|
|
@ -246,19 +246,20 @@ async function getSiteName(info: NodeInfo | null, doc: DOMWindow['document'] | n
|
||||||
|
|
||||||
async function getDescription(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
|
async function getDescription(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
|
||||||
if (info && info.metadata) {
|
if (info && info.metadata) {
|
||||||
if (info.metadata.nodeDescription || info.metadata.description) {
|
const description = info.metadata.nodeDescription || info.metadata.description;
|
||||||
return info.metadata.nodeDescription || info.metadata.description;
|
if (description && description.length < 4096) {
|
||||||
|
return description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc) {
|
if (doc) {
|
||||||
const meta = doc.querySelector('meta[name="description"]')?.getAttribute('content');
|
const meta = doc.querySelector('meta[name="description"]')?.getAttribute('content');
|
||||||
if (meta) {
|
if (meta && meta.length < 4096) {
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
const og = doc.querySelector('meta[property="og:description"]')?.getAttribute('content');
|
const og = doc.querySelector('meta[property="og:description"]')?.getAttribute('content');
|
||||||
if (og) {
|
if (og && og.length < 4096) {
|
||||||
return og;
|
return og;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ const props = withDefaults(defineProps<{
|
||||||
|
|
||||||
const self = props.url.startsWith(local);
|
const self = props.url.startsWith(local);
|
||||||
const uri = new URL(props.url);
|
const uri = new URL(props.url);
|
||||||
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');
|
if (!['http:', 'https:'].includes(uri.protocol)) throw new Error('invalid url');
|
||||||
let el: HTMLElement | null = $ref(null);
|
let el: HTMLElement | null = $ref(null);
|
||||||
|
|
||||||
let schema = $ref(uri.protocol);
|
let schema = $ref(uri.protocol);
|
||||||
|
|
|
@ -63,10 +63,29 @@
|
||||||
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
|
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
|
||||||
<i class="fas fa-quote-right"></i>
|
<i class="fas fa-quote-right"></i>
|
||||||
</MkA>
|
</MkA>
|
||||||
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ i18n.ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
|
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">
|
||||||
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ i18n.ts.followRequestAccepted }}</span>
|
{{ i18n.ts.youGotNewFollower }}
|
||||||
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ i18n.ts.receiveFollowRequest }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ i18n.ts.accept }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ i18n.ts.reject }}</button></div></span>
|
<div v-if="full">
|
||||||
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ i18n.ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ i18n.ts.accept }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ i18n.ts.reject }}</button></div></span>
|
<MkFollowButton :user="notification.user" :full="true"/>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">
|
||||||
|
{{ i18n.ts.followRequestAccepted }}
|
||||||
|
</span>
|
||||||
|
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">
|
||||||
|
{{ i18n.ts.receiveFollowRequest }}
|
||||||
|
<div v-if="full && !followRequestDone">
|
||||||
|
<button class="_textButton" @click="acceptFollowRequest()">{{ i18n.ts.accept }}</button> |
|
||||||
|
<button class="_textButton" @click="rejectFollowRequest()">{{ i18n.ts.reject }}</button>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">
|
||||||
|
{{ i18n.ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b>
|
||||||
|
<div v-if="full && !groupInviteDone">
|
||||||
|
<button class="_textButton" @click="acceptGroupInvitation()">{{ i18n.ts.accept }}</button> |
|
||||||
|
<button class="_textButton" @click="rejectGroupInvitation()">{{ i18n.ts.reject }}</button>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
<span v-if="notification.type === 'app'" class="text">
|
<span v-if="notification.type === 'app'" class="text">
|
||||||
<Mfm :text="notification.body" :nowrap="!full"/>
|
<Mfm :text="notification.body" :nowrap="!full"/>
|
||||||
</span>
|
</span>
|
||||||
|
|
Loading…
Reference in a new issue