Merge branch 'listening-start' into 'develop'
Fix #1060: Added a new radio based on another user listenings Closes #1060 See merge request funkwhale/funkwhale!1067
This commit is contained in:
commit
8700e1b6f8
|
@ -0,0 +1 @@
|
|||
Added a new radio based on another user listenings (#1060)
|
|
@ -42,6 +42,7 @@ import { WebSocketBridge } from 'django-channels'
|
|||
import GlobalEvents from '@/components/utils/global-events'
|
||||
import moment from 'moment'
|
||||
import locales from './locales'
|
||||
import {getClientOnlyRadio} from '@/radios'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
|
@ -138,6 +139,11 @@ export default {
|
|||
id: 'sidebarPendingReviewRequestCount',
|
||||
handler: this.incrementPendingReviewRequestsCountInSidebar
|
||||
})
|
||||
this.$store.commit('ui/addWebsocketEventHandler', {
|
||||
eventName: 'Listen',
|
||||
id: 'handleListen',
|
||||
handler: this.handleListen
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
let self = this
|
||||
|
@ -175,6 +181,10 @@ export default {
|
|||
eventName: 'user_request.created',
|
||||
id: 'sidebarPendingReviewRequestCount',
|
||||
})
|
||||
this.$store.commit('ui/removeWebsocketEventHandler', {
|
||||
eventName: 'Listen',
|
||||
id: 'handleListen',
|
||||
})
|
||||
this.disconnect()
|
||||
},
|
||||
methods: {
|
||||
|
@ -190,6 +200,14 @@ export default {
|
|||
incrementPendingReviewRequestsCountInSidebar (event) {
|
||||
this.$store.commit('ui/incrementNotifications', {type: 'pendingReviewRequests', value: event.pending_count})
|
||||
},
|
||||
handleListen (event) {
|
||||
if (this.$store.state.radios.current && this.$store.state.radios.running) {
|
||||
let current = this.$store.state.radios.current
|
||||
if (current.clientOnly && current.type === 'account') {
|
||||
getClientOnlyRadio(current).handleListen(current, event, this.$store)
|
||||
}
|
||||
}
|
||||
},
|
||||
async fetchNodeInfo () {
|
||||
let response = await axios.get('instance/nodeinfo/2.0/')
|
||||
this.$store.commit('instance/nodeinfo', response.data)
|
||||
|
|
|
@ -251,6 +251,8 @@ export default {
|
|||
progressInterval: null,
|
||||
maxPreloaded: 3,
|
||||
preloadDelay: 15,
|
||||
listenDelay: 15,
|
||||
listeningRecorded: null,
|
||||
soundsCache: [],
|
||||
soundId: null,
|
||||
playTimeout: null,
|
||||
|
@ -477,6 +479,13 @@ export default {
|
|||
this.getSound(toPreload)
|
||||
this.nextTrackPreloaded = true
|
||||
}
|
||||
if (t > this.listenDelay || d - t < 30) {
|
||||
let onlyTrack = this.$store.state.queue.tracks.length === 1
|
||||
if (this.listeningRecorded != this.currentTrack) {
|
||||
this.listeningRecorded = this.currentTrack
|
||||
this.$store.dispatch('player/trackListened', this.currentTrack)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
seek (step) {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<tags-list label-classes="tiny" :truncate-size="20" :limit="2" :show-more="false" :tags="object.track.tags"></tags-list>
|
||||
|
||||
<div class="extra" v-if="isActivity">
|
||||
<span class="left floated">@{{ object.user.username }}</span>
|
||||
<router-link class="left floated" :to="{name: 'profile.overview', params: {username: object.user.username}}">@{{ object.user.username }}</router-link>
|
||||
<span class="right floated"><human-date :date="object.creation_date" /></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
|
||||
<script>
|
||||
|
||||
import lodash from '@/lodash'
|
||||
export default {
|
||||
props: {
|
||||
customRadioId: {required: false},
|
||||
type: {type: String, required: false},
|
||||
clientOnly: {type: Boolean, default: false},
|
||||
objectId: {default: null}
|
||||
},
|
||||
methods: {
|
||||
|
@ -19,7 +21,12 @@ export default {
|
|||
if (this.running) {
|
||||
this.$store.dispatch('radios/stop')
|
||||
} else {
|
||||
this.$store.dispatch('radios/start', {type: this.type, objectId: this.objectId, customRadioId: this.customRadioId})
|
||||
this.$store.dispatch('radios/start', {
|
||||
type: this.type,
|
||||
objectId: this.objectId,
|
||||
customRadioId: this.customRadioId,
|
||||
clientOnly: this.clientOnly,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -30,7 +37,7 @@ export default {
|
|||
if (!state.running) {
|
||||
return false
|
||||
} else {
|
||||
return current.type === this.type && current.objectId === this.objectId && current.customRadioId === this.customRadioId
|
||||
return current.type === this.type && lodash.isEqual(current.objectId, this.objectId) && current.customRadioId === this.customRadioId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import axios from "axios"
|
||||
import logger from '@/logging'
|
||||
|
||||
// import axios from 'axios'
|
||||
|
||||
const RADIOS = {
|
||||
// some radios are client side only, so we have to implement the populateQueue
|
||||
// method by hand
|
||||
account: {
|
||||
offset: 1,
|
||||
populateQueue({current, dispatch, playNow}) {
|
||||
let params = {scope: `actor:${current.objectId.fullUsername}`, ordering: '-creation_date', page_size: 1, page: this.offset}
|
||||
axios.get('history/listenings', {params}).then((response) => {
|
||||
let latest = response.data.results[0]
|
||||
if (!latest) {
|
||||
logger.default.error('No more tracks')
|
||||
dispatch('stop')
|
||||
}
|
||||
this.offset += 1
|
||||
let append = dispatch('queue/append', {track: latest.track}, {root: true})
|
||||
if (playNow) {
|
||||
append.then(() => {
|
||||
dispatch('queue/last', null, {root: true})
|
||||
})
|
||||
}
|
||||
}, (error) => {
|
||||
logger.default.error('Error while fetching listenings', error)
|
||||
dispatch('stop')
|
||||
})
|
||||
},
|
||||
stop () {
|
||||
this.offset = 1
|
||||
},
|
||||
handleListen (current, event, store) {
|
||||
// XXX: handle actors from other pods
|
||||
if (event.actor.local_id === current.objectId.username) {
|
||||
axios.get(`tracks/${event.object.local_id}`).then((response) => {
|
||||
if (response.data.uploads.length > 0) {
|
||||
store.dispatch('queue/append', {track: response.data, index: store.state.queue.currentIndex + 1})
|
||||
this.offset += 1
|
||||
}
|
||||
}, (error) => {
|
||||
logger.default.error('Cannot retrieve track info', error)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export function getClientOnlyRadio({type}) {
|
||||
return RADIOS[type]
|
||||
}
|
|
@ -127,7 +127,6 @@ export default {
|
|||
})
|
||||
},
|
||||
trackEnded ({dispatch, rootState}, track) {
|
||||
dispatch('trackListened', track)
|
||||
let queueState = rootState.queue
|
||||
if (queueState.currentIndex === queueState.tracks.length - 1) {
|
||||
// we've reached last track of queue, trigger a reload
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import axios from 'axios'
|
||||
import logger from '@/logging'
|
||||
|
||||
import {getClientOnlyRadio} from '@/radios'
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
|
@ -42,11 +44,17 @@ export default {
|
|||
}
|
||||
},
|
||||
actions: {
|
||||
start ({commit, dispatch}, {type, objectId, customRadioId}) {
|
||||
start ({commit, dispatch}, {type, objectId, customRadioId, clientOnly}) {
|
||||
var params = {
|
||||
radio_type: type,
|
||||
related_object_id: objectId,
|
||||
custom_radio: customRadioId
|
||||
custom_radio: customRadioId,
|
||||
}
|
||||
if (clientOnly) {
|
||||
commit('current', {type, objectId, customRadioId, clientOnly})
|
||||
commit('running', true)
|
||||
dispatch('populateQueue', true)
|
||||
return
|
||||
}
|
||||
return axios.post('radios/sessions/', params).then((response) => {
|
||||
logger.default.info('Successfully started radio ', type)
|
||||
|
@ -57,7 +65,10 @@ export default {
|
|||
logger.default.error('Error while starting radio', type)
|
||||
})
|
||||
},
|
||||
stop ({commit}) {
|
||||
stop ({commit, state}) {
|
||||
if (state.current && state.current.clientOnly) {
|
||||
getClientOnlyRadio(state.current).stop()
|
||||
}
|
||||
commit('current', null)
|
||||
commit('running', false)
|
||||
},
|
||||
|
@ -71,6 +82,9 @@ export default {
|
|||
var params = {
|
||||
session: state.current.session
|
||||
}
|
||||
if (state.current.clientOnly) {
|
||||
return getClientOnlyRadio(state.current).populateQueue({current: state.current, dispatch, state, rootState, playNow})
|
||||
}
|
||||
return axios.post('radios/tracks/', params).then((response) => {
|
||||
logger.default.info('Adding track to queue from radio')
|
||||
let append = dispatch('queue/append', {track: response.data.track}, {root: true})
|
||||
|
|
|
@ -31,6 +31,7 @@ export default {
|
|||
'mutation.updated': {},
|
||||
'report.created': {},
|
||||
'user_request.created': {},
|
||||
'Listen': {},
|
||||
},
|
||||
pageTitle: null,
|
||||
routePreferences: {
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
</div>
|
||||
</template>
|
||||
</h1>
|
||||
<div class="ui center aligned text">
|
||||
<radio-button type="account" :object-id="{username: object.preferred_username, fullUsername: object.full_username}" :client-only="true"></radio-button>
|
||||
</div>
|
||||
<div class="ui small hidden divider"></div>
|
||||
<div v-if="$store.getters['ui/layoutVersion'] === 'large'">
|
||||
<rendered-description
|
||||
|
@ -82,6 +85,7 @@ import { mapState } from "vuex"
|
|||
import axios from 'axios'
|
||||
|
||||
import ReportMixin from '@/components/mixins/Report'
|
||||
import RadioButton from "@/components/radios/Button"
|
||||
|
||||
export default {
|
||||
mixins: [ReportMixin],
|
||||
|
@ -89,6 +93,9 @@ export default {
|
|||
username: {type: String, required: true},
|
||||
domain: {type: String, required: false, default: null},
|
||||
},
|
||||
components: {
|
||||
RadioButton,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
object: null,
|
||||
|
|
|
@ -136,7 +136,6 @@ describe('store/player', () => {
|
|||
payload: {test: 'track'},
|
||||
params: {rootState: {queue: {currentIndex: 0, tracks: [1, 2]}}},
|
||||
expectedActions: [
|
||||
{ type: 'trackListened', payload: {test: 'track'} },
|
||||
{ type: 'queue/next', payload: null, options: {root: true} }
|
||||
]
|
||||
})
|
||||
|
@ -147,7 +146,6 @@ describe('store/player', () => {
|
|||
payload: {test: 'track'},
|
||||
params: {rootState: {queue: {currentIndex: 1, tracks: [1, 2]}}},
|
||||
expectedActions: [
|
||||
{ type: 'trackListened', payload: {test: 'track'} },
|
||||
{ type: 'radios/populateQueue', payload: null, options: {root: true} },
|
||||
{ type: 'queue/next', payload: null, options: {root: true} }
|
||||
]
|
||||
|
|
|
@ -58,6 +58,7 @@ describe('store/radios', () => {
|
|||
it('stop', () => {
|
||||
return testAction({
|
||||
action: store.actions.stop,
|
||||
params: {state: {}},
|
||||
expectedMutations: [
|
||||
{ type: 'current', payload: null },
|
||||
{ type: 'running', payload: false }
|
||||
|
|
Loading…
Reference in New Issue