Commit 8700e1b6 authored by Agate's avatar Agate 💬

Merge branch 'listening-start' into 'develop'

Fix #1060: Added a new radio based on another user listenings

Closes #1060

See merge request !1067
parents 464010f0 cd63646f
Pipeline #10086 passed with stages
in 9 minutes and 45 seconds
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
}
}
}
......
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
......
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 }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment