merge: Enable by default and federate "hide online status" (resolves #823) (!807)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/807

Closes #823

Approved-by: Marie <github@yuugi.dev>
Approved-by: dakkar <dakkar@thenautilus.net>
This commit is contained in:
dakkar 2024-12-12 13:08:19 +00:00
commit 943c6414d8
8 changed files with 22 additions and 4 deletions

View file

@ -0,0 +1,11 @@
export class AlterUserHideOnlineStatusDefaultTrue1733754069260 {
name = 'AlterUserHideOnlineStatusDefaultTrue1733754069260'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "hideOnlineStatus" SET DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "hideOnlineStatus" SET DEFAULT false`);
}
}

View file

@ -528,6 +528,7 @@ export class ApRendererService {
discoverable: user.isExplorable, discoverable: user.isExplorable,
publicKey: this.renderKey(user, keypair, '#main-key'), publicKey: this.renderKey(user, keypair, '#main-key'),
isCat: user.isCat, isCat: user.isCat,
hideOnlineStatus: user.hideOnlineStatus,
noindex: user.noindex, noindex: user.noindex,
indexable: !user.noindex, indexable: !user.noindex,
speakAsCat: user.speakAsCat, speakAsCat: user.speakAsCat,

View file

@ -564,6 +564,7 @@ const extension_context_definition = {
speakAsCat: 'firefish:speakAsCat', speakAsCat: 'firefish:speakAsCat',
// Sharkey // Sharkey
sharkey: 'https://joinsharkey.org/ns#', sharkey: 'https://joinsharkey.org/ns#',
hideOnlineStatus: 'sharkey:hideOnlineStatus',
backgroundUrl: 'sharkey:backgroundUrl', backgroundUrl: 'sharkey:backgroundUrl',
listenbrainz: 'sharkey:listenbrainz', listenbrainz: 'sharkey:listenbrainz',
// vcard // vcard

View file

@ -389,6 +389,8 @@ export class ApPersonService implements OnModuleInit {
movedToUri: person.movedTo, movedToUri: person.movedTo,
movedAt: person.movedTo ? new Date() : null, movedAt: person.movedTo ? new Date() : null,
alsoKnownAs: person.alsoKnownAs, alsoKnownAs: person.alsoKnownAs,
// We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic.
hideOnlineStatus: person.hideOnlineStatus !== false,
isExplorable: person.discoverable, isExplorable: person.discoverable,
username: person.preferredUsername, username: person.preferredUsername,
approved: true, approved: true,
@ -585,6 +587,8 @@ export class ApPersonService implements OnModuleInit {
isLocked: person.manuallyApprovesFollowers, isLocked: person.manuallyApprovesFollowers,
movedToUri: person.movedTo ?? null, movedToUri: person.movedTo ?? null,
alsoKnownAs: person.alsoKnownAs ?? null, alsoKnownAs: person.alsoKnownAs ?? null,
// We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic.
hideOnlineStatus: person.hideOnlineStatus !== false,
isExplorable: person.discoverable, isExplorable: person.discoverable,
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image, person.backgroundUrl).catch(() => ({}))), ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image, person.backgroundUrl).catch(() => ({}))),
} as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'speakAsCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>; } as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'speakAsCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;

View file

@ -215,6 +215,7 @@ export interface IActor extends IObject {
}; };
'vcard:bday'?: string; 'vcard:bday'?: string;
'vcard:Address'?: string; 'vcard:Address'?: string;
hideOnlineStatus?: boolean;
noindex?: boolean; noindex?: boolean;
listenbrainz?: string; listenbrainz?: string;
backgroundUrl?: string; backgroundUrl?: string;

View file

@ -32,7 +32,7 @@ export class MiUser {
public lastActiveDate: Date | null; public lastActiveDate: Date | null;
@Column('boolean', { @Column('boolean', {
default: false, default: true,
}) })
public hideOnlineStatus: boolean; public hideOnlineStatus: boolean;

View file

@ -587,7 +587,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
// these two methods need to be kept in sync with // these two methods need to be kept in sync with
// `ApRendererService.renderPerson` // `ApRendererService.renderPerson`
private userNeedsPublishing(oldUser: MiLocalUser, newUser: Partial<MiUser>): boolean { private userNeedsPublishing(oldUser: MiLocalUser, newUser: Partial<MiUser>): boolean {
for (const field of ['avatarId', 'bannerId', 'backgroundId', 'isBot', 'username', 'name', 'isLocked', 'isExplorable', 'isCat', 'noindex', 'speakAsCat', 'movedToUri', 'alsoKnownAs'] as (keyof MiUser)[]) { for (const field of ['avatarId', 'bannerId', 'backgroundId', 'isBot', 'username', 'name', 'isLocked', 'isExplorable', 'isCat', 'noindex', 'speakAsCat', 'movedToUri', 'alsoKnownAs', 'hideOnlineStatus'] as (keyof MiUser)[]) {
if ((field in newUser) && oldUser[field] !== newUser[field]) { if ((field in newUser) && oldUser[field] !== newUser[field]) {
return true; return true;
} }

View file

@ -44,7 +44,7 @@ import MkFolder from '@/components/MkFolder.vue';
import { misskeyApi } from '@/scripts/misskey-api.js'; import { misskeyApi } from '@/scripts/misskey-api.js';
const isLocked = ref(false); const isLocked = ref(false);
const hideOnlineStatus = ref(false); const hideOnlineStatus = ref(true);
const noCrawle = ref(false); const noCrawle = ref(false);
watch([isLocked, hideOnlineStatus, noCrawle], () => { watch([isLocked, hideOnlineStatus, noCrawle], () => {