diff --git a/locales/index.d.ts b/locales/index.d.ts index 39d5fa492e..af1c2479ea 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -436,6 +436,10 @@ export interface Locale extends ILocale { * フォロワー */ "followers": string; + /** + * プリズム + */ + "points": string; /** * フォローされています */ @@ -9291,6 +9295,10 @@ export interface Locale extends ILocale { * 実績を獲得 */ "achievementEarned": string; + /** + * ログインボーナス + */ + "loginbonus": string; /** * 通知テスト */ @@ -9380,6 +9388,10 @@ export interface Locale extends ILocale { * 実績の獲得 */ "achievementEarned": string; + /** + * ログインボーナス + */ + "loginbonus": string; /** * 連携アプリからの通知 */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index fb157821af..1f44f8e40c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -105,6 +105,7 @@ note: "ノート" notes: "ノート" following: "フォロー" followers: "フォロワー" +points: "プリズム" followsYou: "フォローされています" createList: "リスト作成" manageLists: "リストの管理" @@ -2452,6 +2453,7 @@ _notification: roleAssigned: "ロールが付与されました" emptyPushNotificationMessage: "プッシュ通知の更新をしました" achievementEarned: "実績を獲得" + loginbonus: "ログインボーナス" testNotification: "通知テスト" checkNotificationBehavior: "通知の表示を確かめる" sendTestNotification: "テスト通知を送信する" @@ -2476,6 +2478,7 @@ _notification: followRequestAccepted: "フォローが受理された" roleAssigned: "ロールが付与された" achievementEarned: "実績の獲得" + loginbonus: "ログインボーナス" app: "連携アプリからの通知" _actions: diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts index 94d56c883b..e3d4aa75df 100644 --- a/packages/backend/src/core/entities/NotificationEntityService.ts +++ b/packages/backend/src/core/entities/NotificationEntityService.ts @@ -163,6 +163,9 @@ export class NotificationEntityService implements OnModuleInit { ...(notification.type === 'achievementEarned' ? { achievement: notification.achievement, } : {}), + ...(notification.type === 'loginbonus' ? { + loginbonus: notification.loginbonus, + } : {}), ...(notification.type === 'app' ? { body: notification.customBody, header: notification.customHeader, diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index b80a1ec206..9d9c2eaec5 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -404,6 +404,7 @@ export class UserEntityService implements OnModuleInit { userRelations?: Map, userMemos?: Map, pinNotes?: Map, + todayGetPoints?: number, }, ): Promise> { const opts = Object.assign({ @@ -507,7 +508,7 @@ export class UserEntityService implements OnModuleInit { iconUrl: r.iconUrl, displayOrder: r.displayOrder, }))) : undefined, - + ...(user.host == null ? { getPoints: profile!.getPoints } : {}), ...(isDetailed ? { url: profile!.url, uri: user.uri, @@ -602,6 +603,9 @@ export class UserEntityService implements OnModuleInit { achievements: profile!.achievements, loggedInDays: profile!.loggedInDates.length, policies: this.roleService.getUserPolicies(user.id), + ...(opts.todayGetPoints ? { + todayGetPoints: opts.todayGetPoints, + } : {}), } : {}), ...(opts.includeSecrets ? { diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts index 7dbe0b3717..ef70a297a9 100644 --- a/packages/backend/src/models/UserProfile.ts +++ b/packages/backend/src/models/UserProfile.ts @@ -261,6 +261,10 @@ export class MiUserProfile { length: 32, array: true, default: '{}', }) public loggedInDates: string[]; + @Column('integer', { + default: '0', + }) + public getPoints: number; @Column('jsonb', { default: [], diff --git a/packages/backend/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts index d324e3e64a..399aa385ef 100644 --- a/packages/backend/src/server/api/endpoints/i.ts +++ b/packages/backend/src/server/api/endpoints/i.ts @@ -8,13 +8,14 @@ import type { UserProfilesRepository } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; +import { NotificationService } from '@/core/NotificationService.js'; import { ApiError } from '../error.js'; export const meta = { tags: ['account'], requireCredential: true, - kind: "read:account", + kind: 'read:account', res: { type: 'object', @@ -43,7 +44,7 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, - + private notificationService: NotificationService, private userEntityService: UserEntityService, ) { super(meta, paramDef, async (ps, user, token) => { @@ -51,7 +52,7 @@ export default class extends Endpoint { // eslint- const now = new Date(); const today = `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}`; - + let todayGetPoints = 0; // 渡ってきている user はキャッシュされていて古い可能性があるので改めて取得 const userProfile = await this.userProfilesRepository.findOne({ where: { @@ -65,9 +66,16 @@ export default class extends Endpoint { // eslint- } if (!userProfile.loggedInDates.includes(today)) { + todayGetPoints = Math.floor(Math.random() * 5) + 1; this.userProfilesRepository.update({ userId: user.id }, { loggedInDates: [...userProfile.loggedInDates, today], }); + this.userProfilesRepository.update({ userId: user.id }, { + getPoints: userProfile.getPoints + todayGetPoints, + }); + this.notificationService.createNotification(user.id, 'loginbonus', { + loginbonus: todayGetPoints, + }); userProfile.loggedInDates = [...userProfile.loggedInDates, today]; } @@ -75,6 +83,7 @@ export default class extends Endpoint { // eslint- schema: 'MeDetailed', includeSecrets: isSecure, userProfile, + ...(todayGetPoints && { todayGetPoints }), }); }); } diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 01d04c5ca8..18fc67f8eb 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -42,6 +42,7 @@ export const notificationTypes = [ 'achievementEarned', 'app', 'test', + 'loginbonus', ] as const; export const groupedNotificationTypes = [ diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue index 73cd7cd5b3..c010e2ba7e 100644 --- a/packages/frontend/src/components/MkNotification.vue +++ b/packages/frontend/src/components/MkNotification.vue @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
@@ -25,6 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only [$style.t_quote]: notification.type === 'quote', [$style.t_pollEnded]: notification.type === 'pollEnded', [$style.t_achievementEarned]: notification.type === 'achievementEarned', + [$style.t_achievementEarned]: notification.type === 'loginbonus', [$style.t_roleAssigned]: notification.type === 'roleAssigned' && notification.role.iconUrl == null, }]" > @@ -37,6 +38,8 @@ SPDX-License-Identifier: AGPL-3.0-only + +