From d2fb093a353c7fd7f8896c0bf544ace86fe280bf Mon Sep 17 00:00:00 2001 From: Leafus Date: Mon, 19 May 2025 16:34:25 +0000 Subject: [PATCH] feat: add music to user profiles (#7) --- .../migration/1743916276027-ProfileMusic.js | 12 ++ .../src/core/entities/UserEntityService.ts | 1 + packages/backend/src/models/UserProfile.ts | 6 + .../src/server/api/endpoints/i/update.ts | 2 + .../frontend/src/components/MkMediaRange.vue | 3 +- .../frontend/src/pages/settings/profile.vue | 9 + packages/frontend/src/pages/user/home.vue | 5 + .../src/pages/user/index.profilemusic.vue | 172 ++++++++++++++++++ 8 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 packages/backend/migration/1743916276027-ProfileMusic.js create mode 100644 packages/frontend/src/pages/user/index.profilemusic.vue diff --git a/packages/backend/migration/1743916276027-ProfileMusic.js b/packages/backend/migration/1743916276027-ProfileMusic.js new file mode 100644 index 0000000000..2bd061e3ad --- /dev/null +++ b/packages/backend/migration/1743916276027-ProfileMusic.js @@ -0,0 +1,12 @@ +/** @type {import('typeorm').MigrationInterface} */ +export class AddProfileMusic1743916276027 { + name = 'AddProfileMusic1743916276027' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "musicUrl" character varying(2048)`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "musicUrl"`); + } +} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 638eaac16f..1fc8fed693 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -612,6 +612,7 @@ export class UserEntityService implements OnModuleInit { location: profile!.location, birthday: profile!.birthday, listenbrainz: profile!.listenbrainz, + musicUrl: profile!.musicUrl, lang: profile!.lang, fields: profile!.fields, verifiedLinks: profile!.verifiedLinks, diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts index 6ee72e6ddd..164160ab54 100644 --- a/packages/backend/src/models/UserProfile.ts +++ b/packages/backend/src/models/UserProfile.ts @@ -43,6 +43,12 @@ export class MiUserProfile { }) public listenbrainz: string | null; + @Column('varchar', { + length: 2048, nullable: true, + comment: 'The music URL of the User.', + }) + public musicUrl: string | null; + @Column('varchar', { length: 2048, nullable: true, comment: 'The description (bio) of the User.', diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 65dcf6301f..018a73be07 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -201,6 +201,7 @@ export const paramDef = { autoAcceptFollowed: { type: 'boolean' }, noCrawle: { type: 'boolean' }, preventAiLearning: { type: 'boolean' }, + musicUrl: { type: 'string', nullable: true }, noindex: { type: 'boolean' }, requireSigninToViewContents: { type: 'boolean' }, makeNotesFollowersOnlyBefore: { type: 'integer', nullable: true }, @@ -335,6 +336,7 @@ export default class extends Endpoint { // eslint- if (ps.location !== undefined) profileUpdates.location = ps.location; if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday; if (ps.listenbrainz !== undefined) profileUpdates.listenbrainz = ps.listenbrainz; + if (ps.musicUrl !== undefined) profileUpdates.musicUrl = ps.musicUrl; if (ps.followingVisibility !== undefined) profileUpdates.followingVisibility = ps.followingVisibility; if (ps.followersVisibility !== undefined) profileUpdates.followersVisibility = ps.followersVisibility; if (ps.chatScope !== undefined) updates.chatScope = ps.chatScope; diff --git a/packages/frontend/src/components/MkMediaRange.vue b/packages/frontend/src/components/MkMediaRange.vue index 9689dc5cfa..e4bbeda156 100644 --- a/packages/frontend/src/components/MkMediaRange.vue +++ b/packages/frontend/src/components/MkMediaRange.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ Math.round(buffer * 100) }}% buffered - +
@@ -26,6 +26,7 @@ withDefaults(defineProps<{ const emit = defineEmits<{ (ev: 'dragEnded', value: number): void; + (ev: 'input', value: number): void; }>(); const model = defineModel({ required: true }); diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue index 21bc74326a..4904dd4fd0 100644 --- a/packages/frontend/src/pages/settings/profile.vue +++ b/packages/frontend/src/pages/settings/profile.vue @@ -57,6 +57,13 @@ SPDX-License-Identifier: AGPL-3.0-only + + + + + + + @@ -222,6 +229,7 @@ const profile = reactive({ followedMessage: $i.followedMessage, location: $i.location, birthday: $i.birthday, + musicUrl: $i.musicUrl, listenbrainz: $i.listenbrainz, lang: assertVaildLang($i.lang) ? $i.lang : null, isBot: $i.isBot ?? false, @@ -281,6 +289,7 @@ function save() { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing birthday: profile.birthday || null, listenbrainz: profile.listenbrainz || null, + musicUrl: profile.musicUrl || null, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing lang: profile.lang || null, isBot: !!profile.isBot, diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index 51b5675592..4a6bb2fe34 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -143,6 +143,9 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.userPagePinTip }}