add notification sounds (disabled by default)
This commit is contained in:
parent
8c966556f4
commit
3c721442bd
11 changed files with 194 additions and 1 deletions
41
src/components/settings_modal/helpers/float_setting.js
Normal file
41
src/components/settings_modal/helpers/float_setting.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { get, set } from 'lodash'
|
||||||
|
import ModifiedIndicator from './modified_indicator.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ModifiedIndicator
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
path: String,
|
||||||
|
disabled: Boolean,
|
||||||
|
min: Number,
|
||||||
|
expert: [Number, String]
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pathDefault () {
|
||||||
|
const [firstSegment, ...rest] = this.path.split('.')
|
||||||
|
return [firstSegment + 'DefaultValue', ...rest].join('.')
|
||||||
|
},
|
||||||
|
state () {
|
||||||
|
const value = get(this.$parent, this.path)
|
||||||
|
if (value === undefined) {
|
||||||
|
return this.defaultState
|
||||||
|
} else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultState () {
|
||||||
|
return get(this.$parent, this.pathDefault)
|
||||||
|
},
|
||||||
|
isChanged () {
|
||||||
|
return this.state !== this.defaultState
|
||||||
|
},
|
||||||
|
matchesExpertLevel () {
|
||||||
|
return (this.expert || 0) <= this.$parent.expertLevel
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
update (e) {
|
||||||
|
set(this.$parent, this.path, parseFloat(e.target.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/components/settings_modal/helpers/float_setting.vue
Normal file
25
src/components/settings_modal/helpers/float_setting.vue
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
v-if="matchesExpertLevel"
|
||||||
|
class="FloatSetting"
|
||||||
|
>
|
||||||
|
<label :for="path">
|
||||||
|
<slot />
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
:id="path"
|
||||||
|
class="number-input"
|
||||||
|
type="number"
|
||||||
|
:step="step || 0.05"
|
||||||
|
:disabled="disabled"
|
||||||
|
:min="min || 0"
|
||||||
|
:max="max || 1"
|
||||||
|
:value="state"
|
||||||
|
@change="update"
|
||||||
|
>
|
||||||
|
{{ ' ' }}
|
||||||
|
<ModifiedIndicator :changed="isChanged" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./float_setting.js"></script>
|
41
src/components/settings_modal/helpers/text_setting.js
Normal file
41
src/components/settings_modal/helpers/text_setting.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { get, set } from 'lodash'
|
||||||
|
import ModifiedIndicator from './modified_indicator.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ModifiedIndicator
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
path: String,
|
||||||
|
disabled: Boolean,
|
||||||
|
min: Number,
|
||||||
|
expert: [Number, String]
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pathDefault () {
|
||||||
|
const [firstSegment, ...rest] = this.path.split('.')
|
||||||
|
return [firstSegment + 'DefaultValue', ...rest].join('.')
|
||||||
|
},
|
||||||
|
state () {
|
||||||
|
const value = get(this.$parent, this.path)
|
||||||
|
if (value === undefined) {
|
||||||
|
return this.defaultState
|
||||||
|
} else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultState () {
|
||||||
|
return get(this.$parent, this.pathDefault)
|
||||||
|
},
|
||||||
|
isChanged () {
|
||||||
|
return this.state !== this.defaultState
|
||||||
|
},
|
||||||
|
matchesExpertLevel () {
|
||||||
|
return (this.expert || 0) <= this.$parent.expertLevel
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
update (e) {
|
||||||
|
set(this.$parent, this.path, e.target.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/components/settings_modal/helpers/text_setting.vue
Normal file
21
src/components/settings_modal/helpers/text_setting.vue
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
v-if="matchesExpertLevel"
|
||||||
|
class="TextSetting"
|
||||||
|
>
|
||||||
|
<label :for="path">
|
||||||
|
<slot />
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
:id="path"
|
||||||
|
class="text-input"
|
||||||
|
:disabled="disabled"
|
||||||
|
:value="state"
|
||||||
|
@change="update"
|
||||||
|
/>
|
||||||
|
{{ ' ' }}
|
||||||
|
<ModifiedIndicator :changed="isChanged" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./text_setting.js"></script>
|
|
@ -1,4 +1,6 @@
|
||||||
import BooleanSetting from '../helpers/boolean_setting.vue'
|
import BooleanSetting from '../helpers/boolean_setting.vue'
|
||||||
|
import FloatSetting from '../helpers/float_setting.vue'
|
||||||
|
import TextSetting from '../helpers/text_setting.vue'
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
|
|
||||||
const NotificationsTab = {
|
const NotificationsTab = {
|
||||||
|
@ -10,7 +12,9 @@ const NotificationsTab = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
BooleanSetting
|
BooleanSetting,
|
||||||
|
FloatSetting,
|
||||||
|
TextSetting
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
user () {
|
user () {
|
||||||
|
|
|
@ -88,6 +88,37 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="setting-item"
|
||||||
|
>
|
||||||
|
<h2>{{ $t('settings.notification_setting_sounds') }}</h2>
|
||||||
|
<ul class="setting-list">
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="soundOnNotif">
|
||||||
|
{{ $t('settings.sound_on_notification') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<FloatSetting
|
||||||
|
id="soundOnNotifVolume"
|
||||||
|
path="soundOnNotifVolume"
|
||||||
|
>
|
||||||
|
{{ $t('settings.sound_on_notification_volume') }}
|
||||||
|
</FloatSetting>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h3>{{ $t('settings.sound_on_notification_custom') }}</h3>
|
||||||
|
<TextSetting
|
||||||
|
id="soundOnNotifCustom"
|
||||||
|
path="soundOnNotifCustom"
|
||||||
|
>
|
||||||
|
{{ $t('settings.sound_on_notification_custom') }}
|
||||||
|
</TextSetting>
|
||||||
|
<div>{{ $t('settings.sound_on_notification_custom_exp') }}</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<p>{{ $t('settings.notification_mutes') }}</p>
|
<p>{{ $t('settings.notification_mutes') }}</p>
|
||||||
<p>{{ $t('settings.notification_blocks') }}</p>
|
<p>{{ $t('settings.notification_blocks') }}</p>
|
||||||
|
|
|
@ -674,6 +674,7 @@
|
||||||
"notification_setting_hide_if_cw": "Hide the contents of push notifications if under a Content Warning",
|
"notification_setting_hide_if_cw": "Hide the contents of push notifications if under a Content Warning",
|
||||||
"notification_setting_hide_notification_contents": "Hide the sender and contents of push notifications",
|
"notification_setting_hide_notification_contents": "Hide the sender and contents of push notifications",
|
||||||
"notification_setting_privacy": "Privacy",
|
"notification_setting_privacy": "Privacy",
|
||||||
|
"notification_setting_sounds": "Sounds",
|
||||||
"notification_visibility": "Types of notifications to show",
|
"notification_visibility": "Types of notifications to show",
|
||||||
"notification_visibility_bites": "Bites",
|
"notification_visibility_bites": "Bites",
|
||||||
"notification_visibility_emoji_reactions": "Reactions",
|
"notification_visibility_emoji_reactions": "Reactions",
|
||||||
|
@ -763,6 +764,10 @@
|
||||||
"show_page_backgrounds": "Show page-specific backgrounds, e.g. for user profiles",
|
"show_page_backgrounds": "Show page-specific backgrounds, e.g. for user profiles",
|
||||||
"show_wider_shortcuts": "Show wider gap between top panel shortcuts",
|
"show_wider_shortcuts": "Show wider gap between top panel shortcuts",
|
||||||
"show_yous": "Show (You)s",
|
"show_yous": "Show (You)s",
|
||||||
|
"sound_on_notification": "Play a sound when you get a notification",
|
||||||
|
"sound_on_notification_custom": "Custom sounds",
|
||||||
|
"sound_on_notification_custom_exp": "Put URLs to custom sounds in this box, one line for each. If you want one sound to have a different volume, put a semicolon after the link and the volume as a number between 0 and 1.",
|
||||||
|
"sound_on_notification_volume": "Volume of the default notification sound",
|
||||||
"stop_gifs": "Pause animated images until you hover on them",
|
"stop_gifs": "Pause animated images until you hover on them",
|
||||||
"streaming": "Automatically show new posts when scrolled to the top",
|
"streaming": "Automatically show new posts when scrolled to the top",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
@ -109,6 +109,9 @@ export const defaultState = {
|
||||||
virtualScrolling: undefined, // instance default
|
virtualScrolling: undefined, // instance default
|
||||||
sensitiveByDefault: undefined, // instance default
|
sensitiveByDefault: undefined, // instance default
|
||||||
sensitiveIfSubject: undefined,
|
sensitiveIfSubject: undefined,
|
||||||
|
soundOnNotif: false,
|
||||||
|
soundOnNotifVolume: 0.2,
|
||||||
|
soundOnNotifCustom: '',
|
||||||
renderMisskeyMarkdown: undefined,
|
renderMisskeyMarkdown: undefined,
|
||||||
renderMfmOnHover: undefined, // instance default
|
renderMfmOnHover: undefined, // instance default
|
||||||
conversationDisplay: undefined, // instance default
|
conversationDisplay: undefined, // instance default
|
||||||
|
|
|
@ -67,6 +67,9 @@ const defaultState = {
|
||||||
virtualScrolling: true,
|
virtualScrolling: true,
|
||||||
sensitiveByDefault: false,
|
sensitiveByDefault: false,
|
||||||
sensitiveIfSubject: true,
|
sensitiveIfSubject: true,
|
||||||
|
soundOnNotif: false,
|
||||||
|
soundOnNotifVolume: 0.2,
|
||||||
|
soundOnNotifCustom: '',
|
||||||
renderMisskeyMarkdown: true,
|
renderMisskeyMarkdown: true,
|
||||||
renderMfmOnHover: false,
|
renderMfmOnHover: false,
|
||||||
conversationDisplay: 'linear',
|
conversationDisplay: 'linear',
|
||||||
|
|
|
@ -134,5 +134,24 @@ export const prepareNotificationObject = (notification, i18n, store) => {
|
||||||
notifObj.image = status.attachments[0].url
|
notifObj.image = status.attachments[0].url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (store.getters.mergedConfig.soundOnNotif) {
|
||||||
|
if (store.getters.mergedConfig.soundOnNotifCustom !== '') {
|
||||||
|
var soundList = store.getters.mergedConfig.soundOnNotifCustom.split("\n")
|
||||||
|
var randomSound = soundList[Math.floor(Math.random() * soundList.length)]
|
||||||
|
var soundVol = (randomSound.split(";").length > 1 ? randomSound.split(";")[1] : store.getters.mergedConfig.soundOnNotifVolume)
|
||||||
|
|
||||||
|
var sound = new Audio(randomSound.split(";")[0])
|
||||||
|
sound.volume = soundVol
|
||||||
|
sound.play()
|
||||||
|
} else {
|
||||||
|
var soundList = ['/static/misskey-notif.mp3']
|
||||||
|
randomSound = soundList[Math.floor(Math.random() * soundList.length)]
|
||||||
|
|
||||||
|
var sound = new Audio(randomSound)
|
||||||
|
sound.volume = store.getters.mergedConfig.soundOnNotifVolume
|
||||||
|
sound.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return notifObj
|
return notifObj
|
||||||
}
|
}
|
||||||
|
|
BIN
static/misskey-notif.mp3
Normal file
BIN
static/misskey-notif.mp3
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue