Skip to content

Commit

Permalink
拡張通知機能
Browse files Browse the repository at this point in the history
  • Loading branch information
mei23 committed May 2, 2019
1 parent 501442c commit 18771d4
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 12 deletions.
6 changes: 6 additions & 0 deletions locales/en-US.yml
Expand Up @@ -126,6 +126,7 @@ common:
apps: "Apps"
tags: "Hashtag"
mute-and-block: "Mute / Block"
extended-notification: "Extra notification"
blocking: "Block"
security: "Security"
signin: "Login History"
Expand Down Expand Up @@ -976,6 +977,11 @@ common/views/components/mute-and-block.vue:
muted-words: "Muted keywords"
muted-words-description: "Separating with spaces results in AND specifications, and delimiting with line breaks results in OR specifications"
save: "Save"
common/views/components/settings/extended-notification.vue:
extended-notification: "Extra notification"
highlighted-words: "Hightlighted words"
highlighted-words-description: "Enter the words you want to notify, one per line"
save: "Save"
common/views/components/password-settings.vue:
reset: "Change password"
enter-current-password: "Enter the current password"
Expand Down
7 changes: 7 additions & 0 deletions locales/ja-JP.yml
Expand Up @@ -136,6 +136,7 @@ common:
apps: "アプリ"
tags: "ハッシュタグ"
mute-and-block: "ミュート/ブロック"
extended-notification: "拡張通知"
blocking: "ブロック"
security: "セキュリティ"
signin: "ログイン履歴"
Expand Down Expand Up @@ -1079,6 +1080,12 @@ common/views/components/mute-and-block.vue:
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
save: "保存"

common/views/components/settings/extended-notification.vue:
extended-notification: "拡張通知"
highlighted-words: "ハイライトワード"
highlighted-words-description: "通知したいワードを1行に1つずつ入力します"
save: "保存"

common/views/components/password-settings.vue:
reset: "パスワードを変更する"
enter-current-password: "現在のパスワードを入力してください"
Expand Down
7 changes: 7 additions & 0 deletions src/client/app/common/scripts/compose-notification.ts
Expand Up @@ -64,6 +64,13 @@ export default function(type, data): Notification {
icon: data.user.avatarUrl
};

case 'highlight':
return {
title: `${getUserName(data.user)}:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl
};

default:
return null;
}
Expand Down
@@ -0,0 +1,47 @@
<template>
<ui-card>
<template #title><fa :icon="faLightbulb"/> {{ $t('extended-notification') }}</template>

<section>
<header>{{ $t('highlighted-words') }}</header>
<ui-textarea v-model="highlightedWords">
{{ $t('highlighted-words') }}<template #desc>{{ $t('highlighted-words-description') }}</template>
</ui-textarea>
<ui-button @click="save">{{ $t('save') }}</ui-button>
</section>
</ui-card>
</template>

<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../i18n';
import { faLightbulb } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n('common/views/components/settings/extended-notification.vue'),
data() {
return {
highlightedWords: '',
faLightbulb,
};
},
computed: {
_highlightedWords: {
get() { return this.$store.state.settings.highlightedWords; },
set(value) { this.$store.dispatch('settings/set', { key: 'highlightedWords', value }); }
},
},
mounted() {
this.highlightedWords = this._highlightedWords.join('\n');
},
methods: {
save() {
this._highlightedWords = this.highlightedWords.split('\n').filter((x: string) => x != '');
}
}
});
</script>
6 changes: 6 additions & 0 deletions src/client/app/common/views/components/settings/settings.vue
Expand Up @@ -183,6 +183,10 @@
<x-mute-and-block/>
</template>

<template v-if="page == null || page == 'extendedNotification'">
<x-extended-notification/>
</template>

<!--
<template v-if="page == null || page == 'apps'">
<ui-card>
Expand Down Expand Up @@ -264,6 +268,7 @@ import XIntegration from './integration.vue';
import XTheme from './theme.vue';
import XDrive from './drive.vue';
import XMuteAndBlock from './mute-and-block.vue';
import XExtendedNotification from './extended-notification.vue';
import XPassword from './password.vue';
import XProfile from './profile.vue';
import XApi from './api.vue';
Expand All @@ -284,6 +289,7 @@ export default Vue.extend({
XTheme,
XDrive,
XMuteAndBlock,
XExtendedNotification,
XPassword,
XProfile,
XApi,
Expand Down
23 changes: 22 additions & 1 deletion src/client/app/common/views/deck/deck.notification.vue
Expand Up @@ -80,6 +80,22 @@
</div>
</div>

<div class="notification highlight" v-if="notification.type == 'highlight'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
<fa :icon="faLightbulb"/>
<router-link :to="notification.user | userPage">
<mk-user-name :user="notification.user"/>
</router-link>
<mk-time :time="notification.createdAt"/>
</header>
<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)">
<mfm :text="getNoteSummary(notification.note)" :should-break="false" :plain-text="true" :custom-emojis="notification.note.emojis"/>
</router-link>
</div>
</div>

<template v-if="notification.type == 'quote'">
<mk-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
Expand All @@ -97,12 +113,14 @@
<script lang="ts">
import Vue from 'vue';
import getNoteSummary from '../../../../../misc/get-note-summary';
import { faLightbulb } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
props: ['notification'],
data() {
return {
getNoteSummary
getNoteSummary,
faLightbulb,
};
},
methods: {
Expand Down Expand Up @@ -186,4 +204,7 @@ export default Vue.extend({
> div > header [data-icon]
color #888
&.reply, &.mention, &.highlight
> div > header [data-icon]
color #555
</style>
20 changes: 18 additions & 2 deletions src/client/app/desktop/views/components/notifications.vue
Expand Up @@ -123,6 +123,20 @@
</router-link>
</div>
</template>

<template v-if="notification.type == 'highlight'">
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
<p><fa :icon="faLightbulb"/>
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">
<mk-user-name :user="notification.note.user"/>
</router-link>
</p>
<a class="note-preview" :href="notification.note | notePage" :title="getNoteSummary(notification.note)">
<mfm :text="getNoteSummary(notification.note)" :should-break="false" :plain-text="true" :custom-emojis="notification.note.emojis"/>
</a>
</div>
</template>
</div>

<p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'">
Expand All @@ -145,6 +159,7 @@ import i18n from '../../../i18n';
import getNoteSummary from '../../../../../misc/get-note-summary';
import getNotificationSummary from '../../../../../misc/get-notification-summary';
import * as config from '../../../config';
import { faLightbulb } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n(),
Expand All @@ -155,7 +170,8 @@ export default Vue.extend({
notifications: [],
moreNotifications: false,
connection: null,
getNoteSummary
getNoteSummary,
faLightbulb,
};
},
Expand Down Expand Up @@ -334,7 +350,7 @@ export default Vue.extend({
.text p [data-icon]
color #888
&.reply, &.mention
&.reply, &.mention, &.highlight
.text p [data-icon]
color #555
Expand Down
3 changes: 3 additions & 0 deletions src/client/app/desktop/views/components/settings.vue
Expand Up @@ -8,6 +8,7 @@
<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</p>
<p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'"><fa icon="hashtag" fixed-width/>{{ $t('@._settings.tags') }}</p>
<p :class="{ active: page == 'muteAndBlock' }" @mousedown="page = 'muteAndBlock'"><fa icon="ban" fixed-width/>{{ $t('@._settings.mute-and-block') }}</p>
<p :class="{ active: page == 'extendedNotification' }" @mousedown="page = 'extendedNotification'"><fa :icon="faLightbulb" fixed-width/>{{ $t('@._settings.extended-notification') }}</p>
<p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'"><fa icon="puzzle-piece" fixed-width/>{{ $t('@._settings.apps') }}</p>
<p :class="{ active: page == 'security' }" @mousedown="page = 'security'"><fa icon="unlock-alt" fixed-width/>{{ $t('@._settings.security') }}</p>
<p :class="{ active: page == 'api' }" @mousedown="page = 'api'"><fa icon="key" fixed-width/>API</p>
Expand All @@ -23,6 +24,7 @@
import Vue from 'vue';
import i18n from '../../../i18n';
import XSettings from '../../../common/views/components/settings/settings.vue';
import { faLightbulb } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n(),
Expand All @@ -43,6 +45,7 @@ export default Vue.extend({
data() {
return {
page: this.initialPage || 'profile',
faLightbulb,
};
},
});
Expand Down
12 changes: 11 additions & 1 deletion src/client/app/mobile/views/components/notification-preview.vue
Expand Up @@ -61,18 +61,28 @@
<p class="note-ref"><fa icon="quote-left"/>{{ getNoteSummary(notification.note) }}<fa icon="quote-right"/></p>
</div>
</template>

<template v-if="notification.type == 'highlight'">
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
<p><fa :icon="faLightbulb"/><mk-user-name :user="notification.note.user"/></p>
<p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
</div>
</template>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import getNoteSummary from '../../../../../misc/get-note-summary';
import { faLightbulb } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
props: ['notification'],
data() {
return {
getNoteSummary
getNoteSummary,
faLightbulb,
};
}
});
Expand Down
23 changes: 22 additions & 1 deletion src/client/app/mobile/views/components/notification.vue
Expand Up @@ -70,6 +70,22 @@
</div>
</div>

<div class="notification highlight" v-if="notification.type == 'highlight'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
<fa :icon="faLightbulb"/>
<router-link :to="notification.user | userPage">
<mk-user-name :user="notification.user"/>
</router-link>
<mk-time :time="notification.createdAt"/>
</header>
<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)">
<mfm :text="getNoteSummary(notification.note)" :should-break="false" :plain-text="true" :custom-emojis="notification.note.emojis"/>
</router-link>
</div>
</div>

<template v-if="notification.type == 'quote'">
<mk-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
Expand All @@ -87,12 +103,14 @@
<script lang="ts">
import Vue from 'vue';
import getNoteSummary from '../../../../../misc/get-note-summary';
import { faLightbulb } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
props: ['notification'],
data() {
return {
getNoteSummary
getNoteSummary,
faLightbulb,
};
},
methods: {
Expand Down Expand Up @@ -176,4 +194,7 @@ export default Vue.extend({
> div > header [data-icon]
color #888
&.reply, &.mention, &.highlight
> div > header [data-icon]
color #555
</style>
2 changes: 2 additions & 0 deletions src/misc/get-notification-summary.ts
Expand Up @@ -22,6 +22,8 @@ export default function(notification: any): string {
return `${getReactionEmoji(notification.reaction)} ${getUserName(notification.user)} ${getNoteSummary(notification.note)}`;
case 'poll_vote':
return `Vote ${getUserName(notification.user)} ${getNoteSummary(notification.note)}`;
case 'highlight':
return `Highlight ${getUserName(notification.user)} ${getNoteSummary(notification.note)}`;
default:
return `Unknown ${notification.type}`;
}
Expand Down
3 changes: 2 additions & 1 deletion src/models/notification.ts
Expand Up @@ -44,7 +44,7 @@ export interface INotification {
* reaction - (自分または自分がWatchしている)投稿にリアクションされた
* poll_vote - (自分または自分がWatchしている)投稿の投票に投票された
*/
type: 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'poll_vote';
type: 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'poll_vote' | 'highlight';

/**
* 通知が読まれたかどうか
Expand Down Expand Up @@ -102,6 +102,7 @@ export const pack = (notification: any) => new Promise<any>(async (resolve, reje
case 'quote':
case 'reaction':
case 'poll_vote':
case 'highlight':
// Populate note
_notification.note = await packNote(_notification.noteId, me);

Expand Down
4 changes: 2 additions & 2 deletions src/server/api/endpoints/i/notifications.ts
Expand Up @@ -46,12 +46,12 @@ export const meta = {
},

includeTypes: {
validator: $.optional.arr($.str.or(['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'poll_vote', 'receiveFollowRequest'])),
validator: $.optional.arr($.str.or(['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'poll_vote', 'receiveFollowRequest', 'highlight'])),
default: [] as string[]
},

excludeTypes: {
validator: $.optional.arr($.str.or(['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'poll_vote', 'receiveFollowRequest'])),
validator: $.optional.arr($.str.or(['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'poll_vote', 'receiveFollowRequest', 'highlight'])),
default: [] as string[]
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/server/api/openapi/schemas.ts
Expand Up @@ -221,7 +221,7 @@ export const schemas = {
},
type: {
type: 'string',
enum: ['follow', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'poll_vote'],
enum: ['follow', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'poll_vote', 'highlight'],
description: 'The type of the notification.'
},
},
Expand Down

0 comments on commit 18771d4

Please sign in to comment.