implement optional confetti on announcements
This commit is contained in:
parent
69f3c8a58e
commit
45bf8262aa
12 changed files with 60 additions and 1 deletions
|
|
@ -1501,6 +1501,8 @@ _announcement:
|
|||
dialogAnnouncementUxWarn: "Having two or more dialog-style notifications simultaneously can significantly impact the user experience, so please use them carefully."
|
||||
silence: "No notification"
|
||||
silenceDescription: "Turning this on will skip the notification of this announcement and the user won't need to read it."
|
||||
confetti: "Throw confetti"
|
||||
confettiDescription: "If enabled, the announcement will display a confetti effect when viewed."
|
||||
_initialAccountSetting:
|
||||
accountCreated: "Your account was successfully created!"
|
||||
letsStartAccountSetup: "For starters, let's set up your profile."
|
||||
|
|
|
|||
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
|
|
@ -13346,6 +13346,10 @@ export interface Locale extends ILocale {
|
|||
* Don't delete files used as avatars&c
|
||||
*/
|
||||
"keepFilesInUse": string;
|
||||
/**
|
||||
* this option requires more complicated database queries, you may need to increase the value of db.extra.statement_timeout in the configuration file
|
||||
*/
|
||||
"keepFilesInUseDescription": string;
|
||||
};
|
||||
}
|
||||
declare const locales: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: bunnybeam and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class AnnouncementConfetti1751912435779 {
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "announcement" ADD "confetti" boolean NOT NULL DEFAULT false`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_94aabe9f742bc9808264a1c97c" ON "announcement" ("confetti") `);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_94aabe9f742bc9808264a1c97c"`);
|
||||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "confetti"`);
|
||||
}
|
||||
}
|
||||
|
|
@ -78,6 +78,7 @@ export class AnnouncementService {
|
|||
forExistingUsers: values.forExistingUsers,
|
||||
silence: values.silence,
|
||||
needConfirmationToRead: values.needConfirmationToRead,
|
||||
confetti: values.confetti,
|
||||
userId: values.userId,
|
||||
});
|
||||
|
||||
|
|
@ -130,6 +131,7 @@ export class AnnouncementService {
|
|||
forExistingUsers: values.forExistingUsers,
|
||||
silence: values.silence,
|
||||
needConfirmationToRead: values.needConfirmationToRead,
|
||||
confetti: values.confetti,
|
||||
isActive: values.isActive,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ export class AnnouncementEntityService {
|
|||
forYou: announcement.userId === me?.id,
|
||||
needConfirmationToRead: announcement.needConfirmationToRead,
|
||||
silence: announcement.silence,
|
||||
confetti: announcement.confetti,
|
||||
isRead: announcement.isRead !== null ? announcement.isRead : undefined,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,12 @@ export class MiAnnouncement {
|
|||
})
|
||||
public silence: boolean;
|
||||
|
||||
@Index()
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public confetti: boolean;
|
||||
|
||||
@Index()
|
||||
@Column({
|
||||
...id(),
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ export const packedAnnouncementSchema = {
|
|||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
confetti: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
forYou: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ export const paramDef = {
|
|||
forExistingUsers: { type: 'boolean', default: false },
|
||||
silence: { type: 'boolean', default: false },
|
||||
needConfirmationToRead: { type: 'boolean', default: false },
|
||||
confetti: { type: 'boolean', default: false },
|
||||
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
||||
},
|
||||
required: ['title', 'text', 'imageUrl'],
|
||||
|
|
@ -83,6 +84,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
forExistingUsers: ps.forExistingUsers,
|
||||
silence: ps.silence,
|
||||
needConfirmationToRead: ps.needConfirmationToRead,
|
||||
confetti: ps.confetti,
|
||||
userId: ps.userId,
|
||||
}, me);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
forExistingUsers: announcement.forExistingUsers,
|
||||
silence: announcement.silence,
|
||||
needConfirmationToRead: announcement.needConfirmationToRead,
|
||||
confetti: announcement.confetti,
|
||||
userId: announcement.userId,
|
||||
reads: reads.get(announcement)!,
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ export const paramDef = {
|
|||
forExistingUsers: { type: 'boolean' },
|
||||
silence: { type: 'boolean' },
|
||||
needConfirmationToRead: { type: 'boolean' },
|
||||
confetti: { type: 'boolean' },
|
||||
isActive: { type: 'boolean' },
|
||||
},
|
||||
required: ['id'],
|
||||
|
|
@ -67,6 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
forExistingUsers: ps.forExistingUsers,
|
||||
silence: ps.silence,
|
||||
needConfirmationToRead: ps.needConfirmationToRead,
|
||||
confetti: ps.confetti,
|
||||
isActive: ps.isActive,
|
||||
}, me);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
|
||||
{{ i18n.ts._announcement.needConfirmationToRead }}
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="announcement.confetti" :helpText="i18n.ts._announcement.confettiDescription">
|
||||
{{ i18n.ts._announcement.confetti }}
|
||||
</MkSwitch>
|
||||
<p v-if="announcement.reads">{{ i18n.tsx.nUsersRead({ n: announcement.reads }) }}</p>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
|
@ -127,6 +130,7 @@ function add() {
|
|||
forExistingUsers: false,
|
||||
silence: false,
|
||||
needConfirmationToRead: false,
|
||||
confetti: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import * as os from '@/os.js';
|
||||
|
|
@ -57,6 +57,7 @@ import { definePage } from '@/page.js';
|
|||
import { $i } from '@/i.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { updateCurrentAccountPartial } from '@/accounts.js';
|
||||
import { confetti } from '@/utility/confetti.js';
|
||||
|
||||
const props = defineProps<{
|
||||
announcementId: string;
|
||||
|
|
@ -67,11 +68,22 @@ const error = ref<any>(null);
|
|||
const path = computed(() => props.announcementId);
|
||||
|
||||
function fetch() {
|
||||
console.log("aaa");
|
||||
announcement.value = null;
|
||||
misskeyApi('announcements/show', {
|
||||
announcementId: props.announcementId,
|
||||
}).then(async _announcement => {
|
||||
console.log("bbbb");
|
||||
announcement.value = _announcement;
|
||||
console.log("cccc");
|
||||
console.log(announcement.value.confetti);
|
||||
console.log(announcement.value.isRead);
|
||||
if (announcement.value.confetti && !announcement.value.isRead) {
|
||||
console.log("dddd");
|
||||
confetti({
|
||||
duration: 1000 * 3,
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
error.value = err;
|
||||
});
|
||||
|
|
@ -106,6 +118,9 @@ definePage(() => ({
|
|||
title: announcement.value ? announcement.value.title : i18n.ts.announcements,
|
||||
icon: 'ti ti-speakerphone',
|
||||
}));
|
||||
|
||||
onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue