0
0
Fork 0

feat(alert): can customize assets & title for Misskey notification

This commit is contained in:
무라쿠모 2024-08-25 23:19:04 +09:00
parent 1e0b6058cb
commit de6aaeb79b
No known key found for this signature in database
GPG key ID: 139D6573F92DA9F7
10 changed files with 86 additions and 18 deletions

View file

@ -20,6 +20,12 @@ export class UserSetting {
@IsOptional()
template?: string;
@IsOptional()
notificationHeader?: string;
@IsOptional()
notificationIcon?: string;
@IsOptional()
useRanking?: boolean;

View file

@ -28,7 +28,7 @@ export class SessionController {
if (setting.alertMode != null) s.alertMode = setting.alertMode;
if (setting.visibility != null) {
console.log(setting.visibility);
if (setting.visibility === 'public' || setting.visibility === 'users') {
if (setting.visibility === 'public'/* || setting.visibility === 'users'*/) {
throw new BadRequestError('Unsupported visibility');
}
s.visibility = setting.visibility;
@ -36,6 +36,8 @@ export class SessionController {
if (setting.localOnly != null) s.localOnly = setting.localOnly;
if (setting.remoteFollowersOnly != null) s.remoteFollowersOnly = setting.remoteFollowersOnly;
if (setting.template !== undefined) s.template = setting.template;
if (setting.notificationHeader !== undefined) s.notificationHeader = setting.notificationHeader;
if (setting.notificationIcon !== undefined) s.notificationIcon = setting.notificationIcon;
if (setting.useRanking !== undefined) s.useRanking = setting.useRanking;
if (setting.appendHashtag !== undefined) s.appendHashtag = setting.appendHashtag;
if (Object.keys(s).length === 0) return;

View file

@ -81,6 +81,20 @@ export class User implements IUser {
})
public template: string | null;
@Column({
type: 'varchar',
length: 1024,
nullable: true,
})
public notificationHeader: string | null;
@Column({
type: 'varchar',
length: 1024,
nullable: true,
})
public notificationIcon: string | null;
@Column({
type: 'real',
default: 0,

View file

@ -51,8 +51,8 @@ export const sendNoteAlert = async (text: string, user: User) => {
*/
export const sendNotificationAlert = async (text: string, user: User) => {
const res = await api(user.host, 'notifications/create', {
header: 'Misskey Tools with LycheeBridge',
icon: 'https://t.psec.dev/assets/lcb.png',
header: user.notificationHeader ?? 'Misskey Tools with LycheeBridge',
icon: user.notificationIcon ?? 'https://t.psec.dev/assets/lcb.png',
body: text,
}, user.token);

View file

@ -17,6 +17,8 @@ export interface IUser {
template: string | null;
prevRating: number;
rating: number;
notificationHeader: string | null;
notificationIcon: string | null;
bannedFromRanking: boolean;
isAdmin?: boolean;
tokenVersion: number;

View file

@ -51,7 +51,7 @@
"update": "Update",
"shareMisskeyTools": "Share #MisskeyTools",
"shareMisskeyToolsNote": "Try #MisskeyTools !\n\nhttps://t.psec.dev",
"instanceUrlPlaceholder": "k.lapy.link, stella.place, psec.dev...",
"instanceUrlPlaceholder": "oscar.surf, hoto.moe, k.lapy.link...",
"settings": "Settings",
"accentColor": "Accent Color",
"changelog": "Changelog",
@ -104,7 +104,10 @@
"order": "Order",
"showRanking": "Show Ranking",
"useRanking": "Join the Ranking",
"appendHashtag": "Add #misshaialert hashtag in template"
"appendHashtag": "Add #misshaialert hashtag in template",
"notificationHeader": "Misskey Notification Header (Title)",
"notificationIcon": "Misskey Notification Icon (URL)",
"notificationContent": "Notification Content"
},
"_accounts": {
"switchAccount": "Switch your account",

View file

@ -51,7 +51,7 @@
"update": "更新する",
"shareMisskeyTools": "#MisskeyTools をシェアする",
"shareMisskeyToolsNote": "#MisskeyTools はいいぞ\n\nhttps://t.psec.dev",
"instanceUrlPlaceholder": "k.lapy.link, stella.place, psec.dev...",
"instanceUrlPlaceholder": "oscar.surf, hoto.moe, k.lapy.link...",
"settings": "設定",
"accentColor": "アクセントカラー",
"changelog": "更新履歴",
@ -104,7 +104,10 @@
"order": "順位",
"showRanking": "ランキングを見る",
"useRanking": "ランキングに参加する",
"appendHashtag": "#misshaialertハッシュタグをテンプレートに追加"
"appendHashtag": "#misshaialertハッシュタグをテンプレートに追加",
"notificationHeader": "Misskey通知タイトル",
"notificationIcon": "Misskey通知アイコン (URL)",
"notificationContent": "通知内容"
},
"_accounts": {
"switchAccount": "アカウント切り替え",

View file

@ -51,7 +51,7 @@
"update": "업데이트하기",
"shareMisskeyTools": "#MisskeyTools 공유하기",
"shareMisskeyToolsNote": "함께 #MisskeyTools 하지 않으실래요?\n\nhttps://t.psec.dev",
"instanceUrlPlaceholder": "k.lapy.link, stella.place, psec.dev...",
"instanceUrlPlaceholder": "oscar.surf, hoto.moe, k.lapy.link...",
"settings": "설정",
"accentColor": "강조 색상",
"changelog": "업데이트 내역",
@ -104,7 +104,10 @@
"order": "순위",
"showRanking": "랭킹 보기",
"useRanking": "노트왕 랭킹에 이름을 표시하기",
"appendHashtag": "#misshaialert 해시태그를 추가하기"
"appendHashtag": "#misshaialert 해시태그를 추가하기",
"notificationHeader": "Misskey 알림 헤더 (제목)",
"notificationIcon": "Misskey 알림 아이콘 (URL)",
"notificationContent": "알림 내용"
},
"_accounts": {
"switchAccount": "계정 전환",

View file

@ -36,6 +36,8 @@ type SettingDraftType = Partial<Pick<IUser,
| 'localOnly'
| 'remoteFollowersOnly'
| 'template'
| 'notificationHeader'
| 'notificationIcon'
| 'useRanking'
| 'appendHashtag'
>>;
@ -60,6 +62,8 @@ export const MisshaiPage: React.VFC = () => {
localOnly: data?.localOnly ?? false,
remoteFollowersOnly: data?.remoteFollowersOnly ?? false,
template: data?.template ?? null,
notificationHeader: data?.notificationHeader ?? null,
notificationIcon: data?.notificationIcon ?? null,
useRanking: data?.useRanking ?? false,
appendHashtag: data?.appendHashtag ?? true,
});
@ -67,8 +71,10 @@ export const MisshaiPage: React.VFC = () => {
const templateTextarea = useRef<HTMLTextAreaElement>(null);
const availableVisibilities: Visibility[] = [
// 'public',
'home',
'followers'
'followers',
'users',
];
const updateSetting = useCallback((obj: SettingDraftType) => {
@ -102,6 +108,8 @@ export const MisshaiPage: React.VFC = () => {
localOnly: data.localOnly,
remoteFollowersOnly: data.remoteFollowersOnly,
template: data.template,
notificationHeader: data.notificationHeader,
notificationIcon: data.notificationIcon,
useRanking: data.useRanking,
appendHashtag: data.appendHashtag
});
@ -188,6 +196,8 @@ export const MisshaiPage: React.VFC = () => {
}, [session.error]);
const defaultTemplate = t('_template.default');
const defaultHeader = 'Misskey Tools with LycheeBridge';
const defaultIcon = 'https://t.psec.dev/assets/lcb.png';
const remaining = 1024 - (draft.template ?? defaultTemplate).length;
@ -309,6 +319,25 @@ export const MisshaiPage: React.VFC = () => {
<i className="fas fa-circle-question"/>
</button>
</div>
{(draft.alertMode === 'notification' || draft.alertMode === 'both') && (
<>
<label className="input-field">
{t('_missHai.notificationHeader')}
</label>
<input type="text" className="input-field" value={draft.notificationHeader ?? defaultHeader} placeholder={defaultHeader} onChange={(e) => {
dispatchDraft({ notificationHeader: e.target.value });
}}/>
<label className="input-field">
{t('_missHai.notificationIcon')}
</label>
<input type="link" className="input-field" value={draft.notificationIcon ?? defaultIcon} placeholder={defaultIcon} onChange={(e) => {
dispatchDraft({ notificationIcon: e.target.value });
}}/>
</>
)}
<label className="input-field">
{t('_missHai.notificationContent')}
</label>
<div className="textarea-wrapper">
<textarea ref={templateTextarea} className="input-field" value={draft.template ?? defaultTemplate} placeholder={defaultTemplate} style={{height: 240}} onChange={(e) => {
dispatchDraft({ template: e.target.value });
@ -319,7 +348,11 @@ export const MisshaiPage: React.VFC = () => {
<div className="hstack mt-2">
<button className="btn danger" onClick={() => dispatchDraft({ template: null })}>{t('resetToDefault')}</button>
<button className="btn primary" onClick={() => {
updateSettingWithDialog({ template: draft.template === '' ? null : draft.template });
updateSettingWithDialog({
template: draft.template === '' ? null : draft.template,
notificationHeader: draft.notificationHeader === '' ? null : draft.notificationHeader,
notificationIcon: draft.notificationIcon === '' ? null : draft.notificationIcon
});
}} disabled={remaining < 0}>{t('save')}</button>
</div>
</div>

View file

@ -7,7 +7,7 @@ import styled from 'styled-components';
import { useSelector } from '../store';
import { IsMobileProp } from '../misc/is-mobile-prop';
import { Icon } from '@iconify/react';
import { useAnnouncements } from '../hooks/useAnnouncements';
// import { useAnnouncements } from '../hooks/useAnnouncements';
const Hero = styled.div<IsMobileProp>`
display: flex;
@ -34,7 +34,7 @@ const Hero = styled.div<IsMobileProp>`
padding: var(--margin);
border-radius: var(--radius);
background: var(--black-50);
backdrop-filter: blur(4px) brightness(120%);IconMCustard
backdrop-filter: blur(4px) brightness(120%);
display: none;
}
}
@ -68,7 +68,7 @@ export const IndexWelcomePage: React.VFC = () => {
const {isMobile} = useSelector(state => state.screen);
const {t} = useTranslation();
const announcements = useAnnouncements();
// const announcements = useAnnouncements();
return (
<>
@ -81,6 +81,7 @@ export const IndexWelcomePage: React.VFC = () => {
<LoginForm />
</FormWrapper>
</div>
{/*
<div className="announcements">
<h2><i className="fas fa-bell"></i> {t('announcements')}</h2>
<div className="menu xmenu">
@ -91,6 +92,7 @@ export const IndexWelcomePage: React.VFC = () => {
))}
</div>
</div>
*/}
<div className="rects">
<div className="rect"></div>
<div className="rect"></div>