mirror of
https://git.youjo.love/youjo/youjo-fe.git
synced 2025-03-13 21:39:59 +01:00
Merge varis music player
This commit is contained in:
parent
a0df90d7dc
commit
7f33b4de7d
17 changed files with 653 additions and 46 deletions
11
src/App.js
11
src/App.js
|
@ -4,6 +4,7 @@ import InstanceSpecificPanel from './components/instance_specific_panel/instance
|
|||
import FeaturesPanel from './components/features_panel/features_panel.vue'
|
||||
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
|
||||
import ShoutPanel from './components/shout_panel/shout_panel.vue'
|
||||
import MusicPlayer from './components/music_player/music_player.vue'
|
||||
import SettingsModal from './components/settings_modal/settings_modal.vue'
|
||||
import MediaModal from './components/media_modal/media_modal.vue'
|
||||
import ModModal from './components/mod_modal/mod_modal.vue'
|
||||
|
@ -29,7 +30,8 @@ export default {
|
|||
InstanceSpecificPanel,
|
||||
FeaturesPanel,
|
||||
WhoToFollowPanel,
|
||||
ShoutPanel,
|
||||
ShoutPanel,
|
||||
MusicPlayer,
|
||||
MediaModal,
|
||||
SideDrawer,
|
||||
MobilePostStatusButton,
|
||||
|
@ -67,7 +69,7 @@ export default {
|
|||
]
|
||||
},
|
||||
currentUser () { return this.$store.state.users.currentUser },
|
||||
userBackground () { return this.currentUser.background_image },
|
||||
userBackground () { return this.getBackgroundImage },
|
||||
instanceBackground () {
|
||||
return this.mergedConfig.hideInstanceWallpaper
|
||||
? null
|
||||
|
@ -81,7 +83,8 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
shout () { return this.$store.state.shout.joined },
|
||||
shout () { return this.$store.state.shout.joined },
|
||||
song () { return this.$store.getters.hasSong },
|
||||
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
|
||||
showInstanceSpecificPanel () {
|
||||
return this.$store.state.instance.showInstanceSpecificPanel &&
|
||||
|
@ -115,7 +118,7 @@ export default {
|
|||
},
|
||||
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
|
||||
showScrollbars () { return this.$store.getters.mergedConfig.showScrollbars },
|
||||
...mapGetters(['mergedConfig'])
|
||||
...mapGetters(['mergedConfig', 'getBackgroundImage'])
|
||||
},
|
||||
methods: {
|
||||
updateMobileState () {
|
||||
|
|
|
@ -61,6 +61,12 @@
|
|||
class="floating-shout mobile-hidden"
|
||||
:class="{ '-left': shoutboxPosition }"
|
||||
/>
|
||||
<music-player
|
||||
:floating="true"
|
||||
v-if="song"
|
||||
class="floating-music-player mobile-hidden"
|
||||
:class="{ '-left': shoutboxPosition }"
|
||||
/>
|
||||
<MobilePostStatusButton />
|
||||
<UserReportingModal />
|
||||
<PostStatusModal />
|
||||
|
|
|
@ -422,6 +422,18 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
|||
}
|
||||
})
|
||||
|
||||
// someone fix this please
|
||||
router.beforeEach((to, from, next) => {
|
||||
// If you are coming from a profile AND the song is playing AND you need to pause it AAAAND YOU ARENT GOING TO A USER PROFILE... pause it
|
||||
if (from.name === 'user-profile' && store.getters.songState && !store.getters.mergedConfig.pauseOnProfileExit && to.name !== 'user-profile') {
|
||||
store.dispatch('setSongState', false)
|
||||
}
|
||||
if (to.name !== 'user-profile') {
|
||||
store.dispatch('resetBackgroundImage')
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
|
|
95
src/components/music_player/music_player.js
Normal file
95
src/components/music_player/music_player.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faHeadphones,
|
||||
faTimes,
|
||||
faPlay,
|
||||
faPause,
|
||||
faVolumeUp,
|
||||
faVolumeOff,
|
||||
faStepForward,
|
||||
faStepBackward
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
library.add(
|
||||
faHeadphones,
|
||||
faTimes,
|
||||
faPlay,
|
||||
faPause,
|
||||
faVolumeUp,
|
||||
faVolumeOff,
|
||||
faStepForward,
|
||||
faStepBackward
|
||||
)
|
||||
|
||||
const musicPlayer = {
|
||||
props: ['floating'],
|
||||
data () {
|
||||
return {
|
||||
currentMessage: '',
|
||||
collapsed: true,
|
||||
volume: 0,
|
||||
progress: 0,
|
||||
muted: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getCurrentSong () {
|
||||
return this.$store.getters.hasSong
|
||||
},
|
||||
isPlaying () {
|
||||
return this.$store.getters.songState
|
||||
},
|
||||
defaultVolume () {
|
||||
return this.$store.getters.mergedConfig.defaultProfileMusicVolume
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
nextSong () {
|
||||
this.$store.dispatch('playlistNext')
|
||||
},
|
||||
prevSong () {
|
||||
this.$store.dispatch('playlistPrev')
|
||||
},
|
||||
seekPosition () {
|
||||
this.$store.dispatch('setSongPosition', this.progress)
|
||||
},
|
||||
togglePanel () {
|
||||
this.collapsed = !this.collapsed
|
||||
},
|
||||
togglePlay () {
|
||||
this.$store.dispatch('setSongState', !this.isPlaying)
|
||||
},
|
||||
toggleMute () {
|
||||
if (this.muted) {
|
||||
this.$store.dispatch('setSongVolume', this.defaultVolume)
|
||||
} else {
|
||||
this.$store.dispatch('setSongVolume', 0)
|
||||
}
|
||||
this.muted = !this.muted
|
||||
},
|
||||
setVolume () {
|
||||
this.$store.dispatch('setSongVolume', this.volume)
|
||||
},
|
||||
clearQueue () {
|
||||
this.$store.dispatch('setBackgroundMusic', null)
|
||||
this.togglePanel()
|
||||
},
|
||||
created () {
|
||||
this.progress = 0
|
||||
this.volume = this.defaultVolume
|
||||
setInterval(() => {
|
||||
if (this.$store.getters.hasSong) {
|
||||
this.progress = this.$store.getters.songProgress
|
||||
if (this.progress === 100) {
|
||||
this.$store.dispatch('playlistNext')
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default musicPlayer
|
187
src/components/music_player/music_player.vue
Normal file
187
src/components/music_player/music_player.vue
Normal file
|
@ -0,0 +1,187 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="!collapsed || !floating"
|
||||
class="music-panel"
|
||||
>
|
||||
<div class="panel panel-default">
|
||||
<div
|
||||
class="panel-heading timeline-heading"
|
||||
:class="{ 'shout-heading': floating }"
|
||||
@click.stop.prevent="togglePanel"
|
||||
>
|
||||
<div class="title">
|
||||
{{ $t('music_player.title') }}
|
||||
<FAIcon
|
||||
v-if="floating"
|
||||
icon="times"
|
||||
class="close-icon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shout-window">
|
||||
<div class="music-player-controls">
|
||||
<div
|
||||
class="music-player-button"
|
||||
@click.stop.prevent="togglePlay"
|
||||
>
|
||||
<div
|
||||
@click.stop.prevent="prevSong"
|
||||
>
|
||||
<FAIcon
|
||||
icon="step-backward"
|
||||
class="music-player-button"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<FAIcon
|
||||
v-if="isPlaying"
|
||||
icon="pause"
|
||||
class="music-player-button"
|
||||
/>
|
||||
<FAIcon
|
||||
v-else
|
||||
icon="play"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@click.stop.prevent="nextSong"
|
||||
>
|
||||
<FAIcon
|
||||
icon="step-forward"
|
||||
class="music-player-button"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@click.stop.prevent="toggleMute"
|
||||
>
|
||||
<FAIcon
|
||||
v-if="!muted"
|
||||
icon="volume-up"
|
||||
/>
|
||||
<FAIcon
|
||||
v-else
|
||||
icon="volume-off"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
v-model="volume"
|
||||
min="0"
|
||||
max="100"
|
||||
@change.stop.prevent="setVolume"
|
||||
/>
|
||||
<FAIcon
|
||||
icon="times"
|
||||
class="close-icon"
|
||||
@click.stop.prevent="clearQueue"
|
||||
/>
|
||||
</div>
|
||||
<div class="music-player-timeline">
|
||||
<input
|
||||
class="seekbar"
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
v-model="progress"
|
||||
@change.stop.prevent="seekPosition"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="music-panel"
|
||||
>
|
||||
<div class="panel panel-default">
|
||||
<div
|
||||
class="panel-heading -stub timeline-heading shout-heading"
|
||||
@click.stop.prevent="togglePanel"
|
||||
>
|
||||
<div class="title">
|
||||
<FAIcon
|
||||
class="icon"
|
||||
icon="headphones"
|
||||
/>
|
||||
{{ $t('music_player.title') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./music_player.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.floating-music-player {
|
||||
position: fixed;
|
||||
bottom: 5em;
|
||||
z-index: 1000;
|
||||
max-width: 25em;
|
||||
|
||||
&.-left {
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
&:not(.-left) {
|
||||
right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.music-panel {
|
||||
.shout-heading {
|
||||
cursor: pointer;
|
||||
|
||||
.icon {
|
||||
color: $fallback--text;
|
||||
color: var(--panelText, $fallback--text);
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.title svg {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.shout-window {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 20em;
|
||||
padding: 2em;
|
||||
column-gap: 1em;
|
||||
|
||||
.music-player-controls {
|
||||
display: inline-flex;
|
||||
column-gap: 1em;
|
||||
|
||||
.music-player-button {
|
||||
display: inline-flex;
|
||||
column-gap: 2em;
|
||||
}
|
||||
}
|
||||
.music-player-timeline {
|
||||
padding-top: 1em;
|
||||
.seekbar {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shout-window-container {
|
||||
height: 100%;
|
||||
}
|
||||
.music-panel {
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -533,7 +533,56 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.plf.profile_look_feel') }}</h2>
|
||||
<ul class="setting-list">
|
||||
<li>
|
||||
<BooleanSetting path="allowCustomProfiles">
|
||||
{{ $t('settings.plf.allow_custom_profile') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="allowProfileBackgroundDisplay"
|
||||
:disabled="!allowCustomProfiles"
|
||||
>
|
||||
{{ $t('settings.plf.allow_profile_background') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="allowProfileMusicPlay"
|
||||
:disabled="!allowCustomProfiles"
|
||||
>
|
||||
{{ $t('settings.plf.allow_profile_music') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ul class="setting-list suboptions">
|
||||
<li>
|
||||
<BooleanSetting
|
||||
path="pauseOnProfileExit"
|
||||
:disabled="!allowProfileMusicPlay || !allowCustomProfiles"
|
||||
>
|
||||
{{ $t('settings.plf.pause_profile_music') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<IntegerSetting
|
||||
path="defaultProfileMusicVolume"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:disabled="!allowProfileMusicPlay || !allowCustomProfiles"
|
||||
>
|
||||
{{ $t('settings.plf.profile_music_volume') }}
|
||||
</IntegerSetting>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
v-if="user"
|
||||
class="setting-item"
|
||||
|
|
|
@ -12,6 +12,7 @@ import InterfaceLanguageSwitcher from 'src/components/interface_language_switche
|
|||
import BooleanSetting from '../helpers/boolean_setting.vue'
|
||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||
import localeService from 'src/services/locale/locale.service.js'
|
||||
import statusPosterService from '../../../services/status_poster/status_poster.service'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
|
@ -113,6 +114,22 @@ const ProfileTab = {
|
|||
bannerImgSrc () {
|
||||
const src = this.$store.state.users.currentUser.cover_photo
|
||||
return (!src) ? this.defaultBanner : src
|
||||
},
|
||||
// How badly... will this fuck us :awoo_concern:
|
||||
hasBackgroundMusic () {
|
||||
for (let i = 0; i < this.user.fields.length; i++) {
|
||||
if (this.user.fields[i].name.toLowerCase() === 'music') {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
backgroundMusic () {
|
||||
for (let i = 0; i < this.user.fields.length; i++) {
|
||||
if (this.user.fields[i].name.toLowerCase() === 'music') {
|
||||
return this.user.fields[i].value
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -159,6 +176,46 @@ const ProfileTab = {
|
|||
uploadFile (slot, e) {
|
||||
const file = e.target.files[0]
|
||||
if (!file) { return }
|
||||
if (this.overFileSizeLimit(slot, file)) { return }
|
||||
// eslint-disable-next-line no-undef
|
||||
const reader = new FileReader()
|
||||
reader.onload = ({ target }) => {
|
||||
const img = target.result
|
||||
this[slot + 'Preview'] = img
|
||||
this[slot] = file
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
},
|
||||
uploadAudioFile (slot, e) {
|
||||
const formData = new FormData()
|
||||
const store = this.$store
|
||||
const file = e.target.files[0]
|
||||
|
||||
if (!file) { return }
|
||||
if (this.overFileSizeLimit(slot, file)) { return }
|
||||
// Check if user has background music already, otherwise check if we aren't over the fields limit and create new
|
||||
// save the index of the place for later incase it does exist
|
||||
const musicIndex = this.hasBackgroundMusic
|
||||
if (!musicIndex) {
|
||||
if (this.newFields.length >= this.maxFields) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
formData.append('file', file)
|
||||
statusPosterService.uploadMedia({ store, formData })
|
||||
.then((fileData) => {
|
||||
// If we do not a music Index create one
|
||||
// otherwise change the value of the current music index
|
||||
if (!musicIndex) {
|
||||
this.newFields.push({ name: 'Music', value: fileData.url })
|
||||
this.updateProfile()
|
||||
} else {
|
||||
this.newFields[musicIndex].value = fileData.url
|
||||
this.updateProfile()
|
||||
}
|
||||
})
|
||||
},
|
||||
overFileSizeLimit (slot, file) {
|
||||
if (file.size > this.$store.state.instance[slot + 'limit']) {
|
||||
const filesize = fileSizeFormatService.fileSizeFormat(file.size)
|
||||
const allowedsize = fileSizeFormatService.fileSizeFormat(this.$store.state.instance[slot + 'limit'])
|
||||
|
@ -174,16 +231,9 @@ const ProfileTab = {
|
|||
],
|
||||
level: 'error'
|
||||
})
|
||||
return
|
||||
return true
|
||||
}
|
||||
// eslint-disable-next-line no-undef
|
||||
const reader = new FileReader()
|
||||
reader.onload = ({ target }) => {
|
||||
const img = target.result
|
||||
this[slot + 'Preview'] = img
|
||||
this[slot] = file
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
return false
|
||||
},
|
||||
resetAvatar () {
|
||||
const confirmed = window.confirm(this.$t('settings.reset_avatar_confirm'))
|
||||
|
|
|
@ -157,33 +157,53 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.profile_banner') }}</h2>
|
||||
<div class="banner-background-preview">
|
||||
<img :src="user.cover_photo">
|
||||
<button
|
||||
v-if="!isDefaultBanner"
|
||||
class="button-unstyled reset-button"
|
||||
:title="$t('settings.reset_profile_banner')"
|
||||
@click="resetBanner"
|
||||
>
|
||||
<FAIcon
|
||||
icon="times"
|
||||
type="button"
|
||||
<h2>{{ $t('settings.profile_customisation.customise') }}</h2>
|
||||
<ul class="setting-list">
|
||||
<li><h3>{{ $t('settings.profile_customisation.profile_background') }}</h3></li>
|
||||
<li>
|
||||
<div class="banner-background-preview">
|
||||
<img :src="user.background_image">
|
||||
<button
|
||||
v-if="!isDefaultBackground"
|
||||
class="button-unstyled reset-button"
|
||||
:title="$t('settings.reset_profile_background')"
|
||||
@click="resetBackground"
|
||||
>
|
||||
<FAIcon
|
||||
icon="times"
|
||||
type="button"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<p>{{ $t('settings.set_new_profile_background') }}</p>
|
||||
<img
|
||||
v-if="backgroundPreview"
|
||||
class="banner-background-preview"
|
||||
:src="backgroundPreview"
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
@change="uploadFile('background', $event)"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
<li><h3>{{ $t('settings.profile_customisation.profile_music') }}</h3></li>
|
||||
<li>
|
||||
<audio
|
||||
v-if="hasBackgroundMusic"
|
||||
:src="backgroundMusic"
|
||||
controls
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<p>{{ $t('settings.set_new_profile_banner') }}</p>
|
||||
<img
|
||||
v-if="bannerPreview"
|
||||
class="banner-background-preview"
|
||||
:src="bannerPreview"
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
@change="uploadFile('banner', $event)"
|
||||
>
|
||||
</div>
|
||||
<p>{{ $t('settings.set_new_profile_music') }}</p>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
@change="uploadAudioFile('upload', $event)"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<FAIcon
|
||||
v-if="bannerUploading"
|
||||
class="uploading"
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
.floating-shout {
|
||||
position: fixed;
|
||||
bottom: 0.5em;
|
||||
z-index: 1000;
|
||||
z-index: 1001;
|
||||
max-width: 25em;
|
||||
|
||||
&.-left {
|
||||
|
|
|
@ -54,6 +54,7 @@ const UserProfile = {
|
|||
tab: 'statuses',
|
||||
followsTab: 'users',
|
||||
footerRef: null,
|
||||
backgroundMusic: null,
|
||||
note: null,
|
||||
noteLoading: false
|
||||
}
|
||||
|
@ -97,6 +98,16 @@ const UserProfile = {
|
|||
followersTabVisible () {
|
||||
return this.isUs || !this.user.hide_followers
|
||||
},
|
||||
hasMusic () {
|
||||
const totalSongs = []
|
||||
for (let i = 0; i < this.user.fields_text.length; i++) {
|
||||
if (this.user.fields_text[i].name.toLowerCase() === 'music') {
|
||||
totalSongs.push(this.user.fields_text[i].value)
|
||||
}
|
||||
}
|
||||
if (totalSongs.length !== 0) { return totalSongs }
|
||||
return false
|
||||
},
|
||||
currentUser () {
|
||||
return this.$store.state.users.currentUser
|
||||
},
|
||||
|
@ -127,6 +138,7 @@ const UserProfile = {
|
|||
load (userNameOrId) {
|
||||
const loadById = (userId) => {
|
||||
this.userId = userId
|
||||
loadUserCustomisations(userId)
|
||||
const timelines = ['user', 'favorites', 'replies', 'media']
|
||||
timelines.forEach((timeline) => {
|
||||
this.$store.commit('clearTimeline', { timeline: timeline })
|
||||
|
@ -135,7 +147,22 @@ const UserProfile = {
|
|||
// Fetch all pinned statuses immediately
|
||||
this.$store.dispatch('fetchPinnedStatuses', userId)
|
||||
}
|
||||
const loadUserCustomisations = (userId) => {
|
||||
const user = this.$store.getters.findUser(userId)
|
||||
const { allowProfileMusicPlay: allowsMusic, allowProfileBackgroundDisplay: allowsImages } = this.$store.getters.mergedConfig
|
||||
if (user.background_image !== null && allowsImages) {
|
||||
this.$store.dispatch('setBackgroundImage', user.background_image)
|
||||
}
|
||||
|
||||
const userMusic = this.hasMusic
|
||||
|
||||
if (Array.isArray(userMusic)) {
|
||||
this.$store.dispatch('setPlaylist', { append: false, list: userMusic })
|
||||
if (allowsMusic) {
|
||||
this.$store.dispatch('setSongState', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset view
|
||||
this.userId = null
|
||||
this.error = false
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
"shoutbox": {
|
||||
"title": "Shoutbox"
|
||||
},
|
||||
"music_player": {
|
||||
"title": "Music Player"
|
||||
},
|
||||
"chats": {
|
||||
"chats": "Chats",
|
||||
"delete": "Delete",
|
||||
|
@ -691,11 +694,23 @@
|
|||
"pause_on_unfocused": "Pause when tab is not focused",
|
||||
"play_videos_in_modal": "Play videos in a popup frame",
|
||||
"post_look_feel": "Posts Look & Feel",
|
||||
"plf": {
|
||||
"profile_look_feel": "Profile Look & Feel",
|
||||
"allow_custom_profile": "Allow custom profiles",
|
||||
"allow_profile_music": "Allow a profiles music to autoplay",
|
||||
"allow_profile_background": "Allow a profiles background to display",
|
||||
"pause_profile_music": "Continue music after exiting profile?",
|
||||
"profile_music_volume": "Default Volume"
|
||||
},
|
||||
"post_status_content_type": "Default post content type",
|
||||
"posts": "Posts",
|
||||
"preload_images": "Preload images",
|
||||
"presets": "Presets",
|
||||
"profile_background": "Profile background",
|
||||
"profile_customisation": {
|
||||
"customise": "Profile customisation",
|
||||
"profile_background": "Profile background",
|
||||
"profile_music": "Profile music"
|
||||
},
|
||||
"profile_banner": "Profile banner",
|
||||
"profile_fields": {
|
||||
"add_field": "Add field",
|
||||
|
@ -738,6 +753,7 @@
|
|||
"set_new_mascot": "Set new mascot",
|
||||
"set_new_profile_background": "Set new profile background",
|
||||
"set_new_profile_banner": "Set new profile banner",
|
||||
"set_new_profile_music": "Set new profile music",
|
||||
"setting_changed": "Setting is different from default",
|
||||
"setting_server_side": "This setting is tied to your profile and affects all sessions and clients",
|
||||
"settings": "Settings",
|
||||
|
|
|
@ -23,6 +23,7 @@ import chatsModule from './modules/chats.js'
|
|||
import announcementsModule from './modules/announcements.js'
|
||||
import editStatusModule from './modules/editStatus.js'
|
||||
import statusHistoryModule from './modules/statusHistory.js'
|
||||
import musicPlayerModule from './modules/music_player.js'
|
||||
import tagModule from './modules/tags.js'
|
||||
import recentEmojisModule from './modules/recentEmojis.js'
|
||||
|
||||
|
@ -92,7 +93,7 @@ const persistedStateOptions = {
|
|||
api: apiModule,
|
||||
config: configModule,
|
||||
serverSideConfig: serverSideConfigModule,
|
||||
shout: shoutModule,
|
||||
shout: shoutModule,
|
||||
oauth: oauthModule,
|
||||
authFlow: authFlowModule,
|
||||
mediaViewer: mediaViewerModule,
|
||||
|
@ -104,6 +105,7 @@ const persistedStateOptions = {
|
|||
statusHistory: statusHistoryModule,
|
||||
chats: chatsModule,
|
||||
announcements: announcementsModule,
|
||||
musicPlayer: musicPlayerModule,
|
||||
tags: tagModule,
|
||||
recentEmojis: recentEmojisModule,
|
||||
},
|
||||
|
|
|
@ -25,6 +25,11 @@ export const defaultState = {
|
|||
profileVersion: 0,
|
||||
expertLevel: 0, // used to track which settings to show and hide
|
||||
colors: {},
|
||||
allowCustomProfiles: false,
|
||||
allowProfileMusicPlay: false,
|
||||
allowProfileBackgroundDisplay: false,
|
||||
pauseOnProfileExit: true,
|
||||
defaultProfileMusicVolume: 50,
|
||||
theme: undefined,
|
||||
customTheme: undefined,
|
||||
customThemeSource: undefined,
|
||||
|
|
|
@ -19,7 +19,9 @@ const defaultState = {
|
|||
layoutType: 'normal',
|
||||
globalNotices: [],
|
||||
layoutHeight: 0,
|
||||
lastTimeline: null
|
||||
lastTimeline: null,
|
||||
backgroundImage: null,
|
||||
currentUserBackgroundImage: null
|
||||
}
|
||||
|
||||
const interfaceMod = {
|
||||
|
@ -104,6 +106,17 @@ const interfaceMod = {
|
|||
},
|
||||
setLastTimeline (state, value) {
|
||||
state.lastTimeline = value
|
||||
},
|
||||
setBackgroundImage (state, value) {
|
||||
state.backgroundImage = value
|
||||
},
|
||||
// Should only be called on start
|
||||
setCurrentUserBackgroundImage (state, value) {
|
||||
state.backgroundImage = value
|
||||
state.currentUserBackgroundImage = value
|
||||
},
|
||||
resetBackgroundImage (state) {
|
||||
state.backgroundImage = state.currentUserBackgroundImage
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
@ -192,6 +205,21 @@ const interfaceMod = {
|
|||
},
|
||||
setLastTimeline ({ commit }, value) {
|
||||
commit('setLastTimeline', value)
|
||||
},
|
||||
setBackgroundImage ({ commit }, value) {
|
||||
commit('setBackgroundImage', value)
|
||||
},
|
||||
setCurrentUserBackgroundImage ({ commit }, value) {
|
||||
commit('setBackgroundImage', value)
|
||||
commit('setCurrentUserBackgroundImage', value)
|
||||
},
|
||||
resetBackgroundImage ({ commit }) {
|
||||
commit('resetBackgroundImage')
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getBackgroundImage (state) {
|
||||
return state.backgroundImage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
106
src/modules/music_player.js
Normal file
106
src/modules/music_player.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
const musicPlayer = {
|
||||
state: {
|
||||
currentSong: null,
|
||||
songState: null,
|
||||
playlist: [],
|
||||
playlistIndex: null,
|
||||
volume: 0
|
||||
},
|
||||
mutations: {
|
||||
incrementPlaylistIndex (state) {
|
||||
if (state.playlistIndex >= state.playlist.length - 1) { return }
|
||||
state.playlistIndex++
|
||||
},
|
||||
decrimentPlaylistIndex (state) {
|
||||
if (state.playlistIndex <= 0) { return }
|
||||
state.playlistIndex--
|
||||
},
|
||||
setPlaylist (state, value) {
|
||||
if (!value.append) {
|
||||
state.playlist = []
|
||||
state.playlistIndex = 0
|
||||
}
|
||||
state.playlist = value.list
|
||||
this.commit('setSong', state.playlist[state.playlistIndex])
|
||||
},
|
||||
setSong (state, value) {
|
||||
if (state.currentSong != null) {
|
||||
state.currentSong.pause()
|
||||
delete state.currentSong
|
||||
}
|
||||
|
||||
state.currentSong = new Audio(value)
|
||||
},
|
||||
setSongVolume (state, value) {
|
||||
state.volume = value
|
||||
state.currentSong.volume = state.volume / 100
|
||||
},
|
||||
setSongPosition (state, value) {
|
||||
state.currentSong.currentTime = value * state.currentSong.duration / 100
|
||||
},
|
||||
setSongState (state, value) {
|
||||
if (state.currentSong === null) { return }
|
||||
state.songState = value
|
||||
if (state.songState === true) {
|
||||
state.currentSong.play()
|
||||
.catch(() => {
|
||||
state.songState = false
|
||||
})
|
||||
} else {
|
||||
state.currentSong.pause()
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setBackgroundMusic ({ commit, getters }, value) {
|
||||
commit('setSong', value)
|
||||
commit('setSongVolume', getters.mergedConfig.defaultProfileMusicVolume)
|
||||
},
|
||||
setSongVolume ({ commit }, value) {
|
||||
commit('setSongVolume', value)
|
||||
},
|
||||
setSongState ({ commit }, value) {
|
||||
commit('setSongState', value)
|
||||
},
|
||||
setPlaylist ({ commit }, value) {
|
||||
commit('setPlaylist', value)
|
||||
},
|
||||
setSongPosition ({ commit }, value) {
|
||||
commit('setSongPosition', value)
|
||||
},
|
||||
playlistNext ({ commit, getters }) {
|
||||
commit('incrementPlaylistIndex')
|
||||
commit('setSong', getters.getPlaylist[getters.getPlaylistIndex])
|
||||
commit('setSongState', true)
|
||||
commit('setSongVolume', getters.getVolume)
|
||||
},
|
||||
playlistPrev ({ commit, getters }) {
|
||||
commit('decrimentPlaylistIndex')
|
||||
commit('setSong', getters.getPlaylist[getters.getPlaylistIndex])
|
||||
commit('setSongState', true)
|
||||
commit('setSongVolume', getters.getVolume)
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
songState (state) {
|
||||
return state.songState
|
||||
},
|
||||
songProgress (state) {
|
||||
return Math.round(state.currentSong.currentTime / state.currentSong.duration * 100)
|
||||
},
|
||||
hasSong (state) {
|
||||
return state.currentSong
|
||||
},
|
||||
getPlaylistIndex (state) {
|
||||
return state.playlistIndex
|
||||
},
|
||||
getPlaylist (state) {
|
||||
return state.playlist
|
||||
},
|
||||
getVolume (state) {
|
||||
return state.volume
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default musicPlayer
|
|
@ -766,8 +766,8 @@ const statuses = {
|
|||
rootState.api.backendInteractor.fetchRebloggedByUsers({ id })
|
||||
.then(rebloggedByUsers => commit('addRepeats', { id, rebloggedByUsers, currentUser: rootState.users.currentUser }))
|
||||
},
|
||||
search (store, { q, resolve, limit, offset, following, type }) {
|
||||
return store.rootState.api.backendInteractor.search2({ q, resolve, limit, offset, following, type })
|
||||
search (store, { q, resolve, limit, offset, following, type, accountId }) {
|
||||
return store.rootState.api.backendInteractor.search2({ q, resolve, limit, offset, following, type, accountId })
|
||||
.then((data) => {
|
||||
store.commit('addNewUsers', data.accounts)
|
||||
store.commit('addNewStatuses', { statuses: data.statuses })
|
||||
|
|
|
@ -602,6 +602,7 @@ const users = {
|
|||
user.muteIds = []
|
||||
user.domainMutes = []
|
||||
commit('setCurrentUser', user)
|
||||
commit('setCurrentUserBackgroundImage', user.background_image) // Set the background image to reset too
|
||||
commit('addNewUsers', [user])
|
||||
|
||||
store.dispatch('fetchEmoji')
|
||||
|
|
Loading…
Reference in a new issue