mirror of
https://git.boykissers.com/pawkey/pawkey-sk.git
synced 2025-12-20 04:04:16 +00:00
feat: add music to front page of instance (#6)
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddMusicFieldsToMeta1743894419864 implements MigrationInterface {
|
||||
name = 'AddMusicFieldsToMeta1743894419864'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "musicSource" character varying(1024)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "musicEnabled" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "musicEnabled"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "musicSource"`);
|
||||
}
|
||||
}
|
||||
@@ -114,6 +114,8 @@ export class MetaEntityService {
|
||||
sidebarLogoUrl: instance.sidebarLogoUrl,
|
||||
backgroundImageUrl: instance.backgroundImageUrl,
|
||||
logoImageUrl: instance.logoImageUrl,
|
||||
musicSource: instance.musicSource,
|
||||
musicEnabled: instance.musicEnabled,
|
||||
maxNoteTextLength: this.config.maxNoteLength,
|
||||
maxRemoteNoteTextLength: this.config.maxRemoteNoteLength,
|
||||
maxCwLength: this.config.maxCwLength,
|
||||
|
||||
@@ -142,6 +142,17 @@ export class MiMeta {
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public musicSource: string | null;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public musicEnabled: boolean;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024,
|
||||
nullable: true,
|
||||
})
|
||||
public iconUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
|
||||
@@ -321,6 +321,14 @@ export const packedMetaLiteSchema = {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
musicSource: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
musicEnabled: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
privacyPolicyUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
|
||||
@@ -453,6 +453,14 @@ export const meta = {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
musicSource: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
musicEnabled: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
translationTimeout: {
|
||||
type: 'number',
|
||||
optional: false, nullable: false,
|
||||
@@ -696,6 +704,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
app512IconUrl: instance.app512IconUrl,
|
||||
sidebarLogoUrl: instance.sidebarLogoUrl,
|
||||
backgroundImageUrl: instance.backgroundImageUrl,
|
||||
musicSource: instance.musicSource,
|
||||
musicEnabled: instance.musicEnabled,
|
||||
logoImageUrl: instance.logoImageUrl,
|
||||
defaultLightTheme: instance.defaultLightTheme,
|
||||
defaultDarkTheme: instance.defaultDarkTheme,
|
||||
|
||||
@@ -63,6 +63,8 @@ export const paramDef = {
|
||||
app512IconUrl: { type: 'string', nullable: true },
|
||||
sidebarLogoUrl: { type: 'string', nullable: true },
|
||||
backgroundImageUrl: { type: 'string', nullable: true },
|
||||
musicSource: { type: 'string', nullable: true },
|
||||
musicEnabled: { type: 'boolean', nullable: false },
|
||||
logoImageUrl: { type: 'string', nullable: true },
|
||||
name: { type: 'string', nullable: true },
|
||||
shortName: { type: 'string', nullable: true },
|
||||
@@ -316,6 +318,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
set.backgroundImageUrl = ps.backgroundImageUrl;
|
||||
}
|
||||
|
||||
if (ps.musicEnabled !== undefined) {
|
||||
set.musicEnabled = ps.musicEnabled;
|
||||
}
|
||||
|
||||
if (ps.musicSource !== undefined) {
|
||||
set.musicSource = ps.musicSource;
|
||||
}
|
||||
|
||||
if (ps.logoImageUrl !== undefined) {
|
||||
set.logoImageUrl = ps.logoImageUrl;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<template>
|
||||
<div v-if="instance" :class="$style.root">
|
||||
<PwVisitorMusic/>
|
||||
<div :class="[$style.main, $style.panel]">
|
||||
<img :src="instance.sidebarLogoUrl || instance.iconUrl || '/apple-touch-icon.png'" alt="" :class="instance.sidebarLogoUrl ? $style.wideIcon : $style.mainIcon"/>
|
||||
<button class="_button _acrylic" :class="$style.mainMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
|
||||
@@ -61,6 +62,7 @@ import * as Misskey from 'misskey-js';
|
||||
import sanitizeHtml from '@/utility/sanitize-html.js';
|
||||
import XSigninDialog from '@/components/MkSigninDialog.vue';
|
||||
import XSignupDialog from '@/components/MkSignupDialog.vue';
|
||||
import PwVisitorMusic from '@/components/PwVisitorMusic.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkTimeline from '@/components/MkTimeline.vue';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
|
||||
30
packages/frontend/src/components/PwVisitorMusic.vue
Normal file
30
packages/frontend/src/components/PwVisitorMusic.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template v-if="instance">
|
||||
<audio v-if="instance.musicEnabled" ref="audioRef" :src="instance.musicSource" loop></audio>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, onMounted, onUnmounted } from 'vue';
|
||||
import { instance } from '@/instance.js';
|
||||
|
||||
const audioRef = ref<HTMLAudioElement | null>(null);
|
||||
const hasPlayed = ref(false);
|
||||
|
||||
const playMusic = () => {
|
||||
if (audioRef.value && !hasPlayed.value && instance.musicEnabled) {
|
||||
audioRef.value.volume = 0.2;
|
||||
audioRef.value.play().catch(() => {
|
||||
// Ignore autoplay errors
|
||||
});
|
||||
hasPlayed.value = true;
|
||||
document.removeEventListener('click', playMusic);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', playMusic);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', playMusic);
|
||||
});
|
||||
</script>
|
||||
@@ -54,6 +54,16 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template #label>{{ i18n.ts.backgroundImageUrl }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkSwitch v-model="musicEnabled">
|
||||
<template #label>Enable Login Music</template>
|
||||
<template #caption>Play music when users visit the login page</template>
|
||||
</MkSwitch>
|
||||
|
||||
<MkInput v-model="musicSource" type="url">
|
||||
<template #prefix><i class="ti ti-link"></i></template>
|
||||
<template #label>Login Music URL</template>
|
||||
</MkInput>
|
||||
|
||||
<FromSlot>
|
||||
<template #label>{{ i18n.ts.defaultLike }}</template>
|
||||
<MkCustomEmoji v-if="defaultLike.startsWith(':')" style="max-height: 3em; font-size: 1.1em;" :useOriginalSize="false" :name="defaultLike" :normal="true" :noStyle="true"/>
|
||||
@@ -129,6 +139,7 @@ import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { instance, fetchInstance } from '@/instance.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkColorInput from '@/components/MkColorInput.vue';
|
||||
|
||||
@@ -138,6 +149,8 @@ const app192IconUrl = ref<string | null>(null);
|
||||
const app512IconUrl = ref<string | null>(null);
|
||||
const bannerUrl = ref<string | null>(null);
|
||||
const backgroundImageUrl = ref<string | null>(null);
|
||||
const musicSource = ref<string | null>(null);
|
||||
const musicEnabled = ref<boolean>(false);
|
||||
const themeColor = ref<string | null>(null);
|
||||
const defaultLightTheme = ref<string | null>(null);
|
||||
const defaultDarkTheme = ref<string | null>(null);
|
||||
@@ -157,6 +170,8 @@ async function init() {
|
||||
app512IconUrl.value = meta.app512IconUrl;
|
||||
bannerUrl.value = meta.bannerUrl;
|
||||
backgroundImageUrl.value = meta.backgroundImageUrl;
|
||||
musicSource.value = meta.musicSource;
|
||||
musicEnabled.value = meta.musicEnabled;
|
||||
themeColor.value = meta.themeColor;
|
||||
defaultLightTheme.value = meta.defaultLightTheme;
|
||||
defaultDarkTheme.value = meta.defaultDarkTheme;
|
||||
@@ -177,6 +192,8 @@ function save() {
|
||||
app512IconUrl: app512IconUrl.value,
|
||||
bannerUrl: bannerUrl.value,
|
||||
backgroundImageUrl: backgroundImageUrl.value,
|
||||
musicSource: musicSource.value,
|
||||
musicEnabled: musicEnabled.value,
|
||||
themeColor: themeColor.value === '' ? null : themeColor.value,
|
||||
defaultLightTheme: defaultLightTheme.value === '' ? null : defaultLightTheme.value,
|
||||
defaultDarkTheme: defaultDarkTheme.value === '' ? null : defaultDarkTheme.value,
|
||||
|
||||
Reference in New Issue
Block a user