Skip to content

Commit

Permalink
feat: notifications support custom content formats
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiteMinds committed Mar 8, 2024
1 parent 87c3f93 commit 7055808
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 22 deletions.
1 change: 1 addition & 0 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
export interface Settings {
notExitOnAllWindowsClosed: boolean
noticeOnRecordStart: boolean
noticeFormat?: string
debugMode?: boolean
autoGenerateSRTOnRecordStop?: boolean
autoRemoveRecordWhenTinySize?: boolean
Expand Down
2 changes: 2 additions & 0 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
"@types/dplayer": "^1.25.2",
"@types/lodash-es": "^4.17.6",
"@types/ramda": "^0.28.15",
"@types/string-template": "^1.0.6",
"@vitejs/plugin-vue": "^3.1.0",
"autoprefixer": "^10.4.11",
"postcss": "^8.4.16",
"string-template": "^1.0.0",
"tailwindcss": "^3.2.3",
"typescript": "^4.6.4",
"vite": "^3.1.0",
Expand Down
20 changes: 20 additions & 0 deletions packages/web/src/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createI18n } from 'vue-i18n'
import { LARServerService } from './services/LARServerService'
import zhMessages from './messages/zh'
import ruMessages from './messages/ru'
import enMessages from './messages/en'

// TODO: 先简单点,直接在这里调 getSettings,没有本地缓存
const { locale = navigator.language } = await LARServerService.getSettings({})

export const i18n = createI18n({
legacy: false,
locale,
// 系统语言没匹配到的话大概率不是中文使用者,所以默认英文
fallbackLocale: 'en',
messages: {
zh: zhMessages,
ru: ruMessages,
en: enMessages,
},
})
21 changes: 1 addition & 20 deletions packages/web/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
Expand All @@ -9,32 +8,14 @@ import { createRouter } from './router'
import { initStore } from './store'
import { RecordService } from './services/RecordService'
import { InteractionService } from './services/InteractionService'
import zhMessages from './messages/zh'
import ruMessages from './messages/ru'
import enMessages from './messages/en'
import { i18n } from './i18n'
// 这个必须放在下面,权重才能比 vuetify 高
import './style.css'
import { LARServerService } from './services/LARServerService'

// TODO: 先简单点,不做初始化的 loading 之类的,出问题顶多 B/S 模式下的通知出问题
void RecordService.init()
InteractionService.blurSomeElementOnPressEscape = true

// TODO: 先简单点,直接在这里调 getSettings,没有本地缓存
const { locale = navigator.language } = await LARServerService.getSettings({})

const i18n = createI18n({
legacy: false,
locale,
// 系统语言没匹配到的话大概率不是中文使用者,所以默认英文
fallbackLocale: 'en',
messages: {
zh: zhMessages,
ru: ruMessages,
en: enMessages,
},
})

const vuetify = createVuetify({
components,
directives,
Expand Down
1 change: 1 addition & 0 deletions packages/web/src/messages/en.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export default {
settings: {
app_settings: 'Appliaction Settings',
default_notice_format: "Channel {'{channelId}'} started recording",
},
}
1 change: 1 addition & 0 deletions packages/web/src/messages/ru.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export default {
settings: {
app_settings: 'Настройки приложения',
default_notice_format: "Канал {'{channelId}'} начал запись",
},
}
1 change: 1 addition & 0 deletions packages/web/src/messages/zh.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export default {
settings: {
app_settings: '应用设置',
default_notice_format: "频道 {'{channelId}'} 开始录制",
},
}
24 changes: 22 additions & 2 deletions packages/web/src/services/RecordService/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import type { SSEMessage } from '@autorecord/http-server'
import { DebouncedFunc, throttle } from 'lodash-es'
import { tap } from 'rxjs'
import fastMemo from 'fast-memoize'
import formatTemplate from 'string-template'
import { LARServerService } from '../LARServerService'
import { NotificationService } from '../NotificationService'
import { TabService } from '../TabService'
import fastMemo from 'fast-memoize'
import { i18n } from '../../i18n'

// TODO: 这个应该是从服务器拉取一个支持的 providers 列表,临时手写下
const providers = [
{ id: 'DouYu', name: '斗鱼' },
{ id: 'Bilibili', name: 'Bilibili' },
{ id: 'HuYa', name: '虎牙' },
{ id: 'DouYin', name: '抖音' },
]

const getThrottledChannelNotifyFn = fastMemo(function createThrottledChannelNotifyFn(
// 只是提供给 memoize 作为 cache 的 key,实际逻辑中不会使用。
Expand All @@ -16,6 +26,7 @@ const getThrottledChannelNotifyFn = fastMemo(function createThrottledChannelNoti
export async function init() {
const settings = await LARServerService.getSettings({})
RecordService.noticeOnRecordStart = settings.noticeOnRecordStart
RecordService.noticeFormat = settings.noticeFormat ?? ''

const tryNoticeOnRecordStartMsg = tap<SSEMessage>((msg) => {
// TODO: 后面看下优化后的通知效果,如果客户端下表现不太好,可以根据 isClientMode
Expand All @@ -25,10 +36,18 @@ export async function init() {
// 只有一个 tab 能发出通知,不然会重复发
if (TabService.getSelfRole() !== 'leader') return

const noticeFormat =
RecordService.noticeFormat !== '' ? RecordService.noticeFormat : i18n.global.t('settings.default_notice_format')
const providerName = providers.find((p) => p.id === msg.recorder.providerId)?.name ?? '未知'

// 对每个频道的通知单独节流,防止开播、下播时的流不正常造成反复的录制通知。
const notify = getThrottledChannelNotifyFn(msg.recorder.channelId)
notify({
title: `频道 ${msg.recorder.channelId} 开始录制`,
title: formatTemplate(noticeFormat, {
channelId: msg.recorder.channelId,
platform: providerName,
remarks: msg.recorder.remarks ?? '',
}),
body: msg.recorder.remarks,
})
})
Expand All @@ -44,5 +63,6 @@ export async function init() {

export const RecordService = {
noticeOnRecordStart: true,
noticeFormat: '',
init,
}
39 changes: 39 additions & 0 deletions packages/web/src/views/RecordersManage/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,43 @@

<v-checkbox label="录制开始时发出通知" v-model="settings.noticeOnRecordStart" hide-details />

<v-text-field
v-if="settings.noticeOnRecordStart"
label="通知内容格式"
v-model="settings.noticeFormat"
persistent-placeholder
:placeholder="t('settings.default_notice_format')"
append-inner-icon="mdi-help-circle"
@click:append-inner="noticeFormatAlertVisible = !noticeFormatAlertVisible"
/>
<v-alert v-model="noticeFormatAlertVisible" closable>
<v-alert-title>如何在通知内容格式中使用变量?</v-alert-title>
<p class="text-subtitle-1 m-2">使用 `{}` 包裹住变量名即可,如 `频道 {channelId} 开始录制`</p>
<v-table>
<thead>
<tr>
<th class="text-left">变量名</th>
<th class="text-left">变量值</th>
</tr>
</thead>

<tbody>
<tr>
<td>platform</td>
<td>录制的平台名,如 `Bilibili`</td>
</tr>
<tr>
<td>channelId</td>
<td>录制的频道 id,如 `196`</td>
</tr>
<tr>
<td>remarks</td>
<td>频道的备注,为用户自定义的值</td>
</tr>
</tbody>
</v-table>
</v-alert>

<v-checkbox label="调试模式" v-model="settings.debugMode" hide-details />
</v-form>
</v-card-item>
Expand Down Expand Up @@ -193,6 +230,7 @@ const manager = ref<API.getManager.Resp>()
const managerDefault = ref<API.getManagerDefault.Resp>()
const settings = ref<API.getSettings.Resp>()
const savePathRuleAlertVisible = ref(false)
const noticeFormatAlertVisible = ref(false)
// 这里的实现方式是为了让设置页面内部可以预览语言更改后的效果
const { locale: appLocale } = useI18n()
Expand All @@ -218,6 +256,7 @@ const apply = async () => {
const newSettings = await LARServerService.setSettings(settings.value)
// TODO: 前端目前只有 RecordService 用到了 settings,为了降低开发复杂度,这里先直接赋值
RecordService.noticeOnRecordStart = newSettings.noticeOnRecordStart
RecordService.noticeFormat = newSettings.noticeFormat ?? ''
appLocale.value = innerLocale.value
}
Expand Down
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ __metadata:
"@types/dplayer": ^1.25.2
"@types/lodash-es": ^4.17.6
"@types/ramda": ^0.28.15
"@types/string-template": ^1.0.6
"@vitejs/plugin-vue": ^3.1.0
autoprefixer: ^10.4.11
axios: ^0.27.2
Expand All @@ -186,6 +187,7 @@ __metadata:
postcss: ^8.4.16
ramda: ^0.28.0
rxjs: ^7.5.7
string-template: ^1.0.0
tailwindcss: ^3.2.3
typescript: ^4.6.4
uuid: ^9.0.0
Expand Down Expand Up @@ -2252,6 +2254,13 @@ __metadata:
languageName: node
linkType: hard

"@types/string-template@npm:^1.0.6":
version: 1.0.6
resolution: "@types/string-template@npm:1.0.6"
checksum: de68f02804014c390e6c911add2c8865fef61780062b8187e7803cbb5b43603dd0291ffffd1bd135df552878939cc2e0709380cc55203c87bb25281c4d325456
languageName: node
linkType: hard

"@types/uuid@npm:^8.3.4":
version: 8.3.4
resolution: "@types/uuid@npm:8.3.4"
Expand Down

0 comments on commit 7055808

Please sign in to comment.