2015-12-13 04:42:28 +00:00
|
|
|
|
<template>
|
2016-06-25 16:05:24 +00:00
|
|
|
|
<section id="profileWrapper">
|
|
|
|
|
<h1 class="heading">
|
|
|
|
|
<span>Profile & Preferences</span>
|
|
|
|
|
</h1>
|
|
|
|
|
|
|
|
|
|
<div class="main-scroll-wrap">
|
|
|
|
|
<form @submit.prevent="update">
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<label for="inputProfileName">Name</label>
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<input type="text" name="name" id="inputProfileName" v-model="state.current.name">
|
2015-12-13 04:42:28 +00:00
|
|
|
|
</div>
|
2016-06-25 16:05:24 +00:00
|
|
|
|
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<label for="inputProfileEmail">Email Address</label>
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<input type="email" name="email" id="inputProfileEmail" v-model="state.current.email">
|
2016-06-25 16:05:24 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="change-pwd">
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<p class="help">If you want to change your password, enter it below. <br>
|
|
|
|
|
Otherwise, just leave the next two fields empty. It’s OK – no one will blame you.</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<label for="inputProfilePassword">New Password</label>
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<input v-model="pwd" name="password" type="password" id="inputProfilePassword" autocomplete="off">
|
2016-06-25 16:05:24 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<label for="inputProfileConfirmPassword">Confirm Password</label>
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<input v-model="confirmPwd" name="confirmPassword" type="password" id="inputProfileConfirmPassword" autocomplete="off">
|
2016-06-25 16:05:24 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="form-row">
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<button type="submit" class="btn btn-submit">Save</button>
|
2016-06-25 16:05:24 +00:00
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
<div class="preferences">
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<label>
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<input type="checkbox" name="notify" v-model="prefs.notify" @change="savePreference">
|
2016-06-25 16:05:24 +00:00
|
|
|
|
Show “Now Playing” song notification
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-row">
|
|
|
|
|
<label>
|
2016-11-23 15:57:41 +00:00
|
|
|
|
<input type="checkbox" name="confirmClosing" v-model="prefs.confirmClosing" @change="savePreference">
|
2016-06-25 16:05:24 +00:00
|
|
|
|
Confirm before closing Koel
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<section class="lastfm" >
|
|
|
|
|
<h1>Last.fm Integration</h1>
|
|
|
|
|
|
|
|
|
|
<div v-if="sharedState.useLastfm">
|
|
|
|
|
<p>This installation of Koel integrates with Last.fm.
|
|
|
|
|
<span v-if="state.current.preferences.lastfm_session_key">
|
|
|
|
|
It appears that you have connected your Last.fm account as well – Perfect!
|
|
|
|
|
</span>
|
|
|
|
|
<span v-else>
|
|
|
|
|
It appears that you haven’t connected to your Last.fm account thought.
|
|
|
|
|
</span>
|
|
|
|
|
</p>
|
|
|
|
|
<p>
|
|
|
|
|
Connecting Koel and your Last.fm account enables exciting features – scrobbling is one of them.
|
|
|
|
|
</p>
|
|
|
|
|
<p v-if="state.current.preferences.lastfm_session_key">
|
|
|
|
|
For the sake of democracy, you have the option to disconnect from Last.fm too.
|
|
|
|
|
Doing so will reload Koel, though.
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<div class="buttons">
|
|
|
|
|
<button @click.prevent="connectToLastfm" class="connect">
|
|
|
|
|
<i class="fa fa-lastfm"></i>
|
|
|
|
|
{{ state.current.preferences.lastfm_session_key ? 'Reconnect' : 'Connect' }}
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
v-if="state.current.preferences.lastfm_session_key"
|
|
|
|
|
@click.prevent="disconnectFromLastfm"
|
|
|
|
|
class="disconnect"
|
|
|
|
|
>
|
|
|
|
|
Disconnect
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else>
|
|
|
|
|
<p>This installation of Koel has no Last.fm integration.
|
|
|
|
|
<span v-if="state.current.is_admin">Visit
|
|
|
|
|
<a href="https://github.com/phanan/koel/wiki" target="_blank">Koel’s Wiki</a>
|
|
|
|
|
for a quick how-to. Really, you should do it.
|
|
|
|
|
</span>
|
2016-09-23 10:01:55 +00:00
|
|
|
|
<span v-else>Try politely asking your administrator to enable it.</span>
|
2016-06-25 16:05:24 +00:00
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
2015-12-13 04:42:28 +00:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2016-11-26 03:25:35 +00:00
|
|
|
|
import { userStore, preferenceStore, sharedStore } from '../../../stores'
|
2016-12-20 15:44:47 +00:00
|
|
|
|
import { forceReloadWindow, $ } from '../../../utils'
|
2016-11-26 03:25:35 +00:00
|
|
|
|
import { http, ls } from '../../../services'
|
2016-06-25 16:05:24 +00:00
|
|
|
|
|
|
|
|
|
export default {
|
2016-11-26 03:25:35 +00:00
|
|
|
|
data () {
|
2016-06-25 16:05:24 +00:00
|
|
|
|
return {
|
|
|
|
|
state: userStore.state,
|
|
|
|
|
cache: userStore.stub,
|
|
|
|
|
pwd: '',
|
|
|
|
|
confirmPwd: '',
|
|
|
|
|
prefs: preferenceStore.state,
|
2016-11-26 03:25:35 +00:00
|
|
|
|
sharedState: sharedStore.state
|
|
|
|
|
}
|
2016-06-25 16:05:24 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
/**
|
|
|
|
|
* Update the current user's profile.
|
|
|
|
|
*/
|
2016-11-26 03:25:35 +00:00
|
|
|
|
update () {
|
2016-06-25 16:05:24 +00:00
|
|
|
|
// A little validation put in a small place.
|
|
|
|
|
if ((this.pwd || this.confirmPwd) && this.pwd !== this.confirmPwd) {
|
2016-12-20 15:44:47 +00:00
|
|
|
|
document.querySelectorAll('#inputProfilePassword, #inputProfileConfirmPassword')
|
|
|
|
|
.forEach(el => $.addClass(el, 'error'))
|
2016-11-26 03:25:35 +00:00
|
|
|
|
return
|
2016-06-25 16:05:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-20 15:44:47 +00:00
|
|
|
|
document.querySelectorAll('#inputProfilePassword, #inputProfileConfirmPassword')
|
|
|
|
|
.forEach(el => $.removeClass(el, 'error'))
|
2016-06-25 16:05:24 +00:00
|
|
|
|
|
2016-06-27 06:11:35 +00:00
|
|
|
|
userStore.updateProfile(this.pwd).then(() => {
|
2016-11-26 03:25:35 +00:00
|
|
|
|
this.pwd = ''
|
|
|
|
|
this.confirmPwd = ''
|
|
|
|
|
})
|
2016-06-25 16:05:24 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Save the current user's preference.
|
|
|
|
|
*/
|
2016-11-26 03:25:35 +00:00
|
|
|
|
savePreference () {
|
|
|
|
|
this.$nextTick(() => preferenceStore.save())
|
2016-06-25 16:05:24 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Connect the current user to Last.fm.
|
|
|
|
|
* This method opens a new window.
|
|
|
|
|
* Koel will reload once the connection is successful.
|
|
|
|
|
*/
|
2016-11-26 03:25:35 +00:00
|
|
|
|
connectToLastfm () {
|
2016-06-25 16:05:24 +00:00
|
|
|
|
window.open(
|
|
|
|
|
`/api/lastfm/connect?jwt-token=${ls.get('jwt-token')}`,
|
|
|
|
|
'_blank',
|
|
|
|
|
'toolbar=no,titlebar=no,location=no,width=1024,height=640'
|
2016-11-26 03:25:35 +00:00
|
|
|
|
)
|
2016-06-25 16:05:24 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Disconnect the current user from Last.fm.
|
|
|
|
|
* Oh God why.
|
|
|
|
|
*/
|
2016-11-26 03:25:35 +00:00
|
|
|
|
disconnectFromLastfm () {
|
2016-06-25 16:05:24 +00:00
|
|
|
|
// Should we use userStore?
|
|
|
|
|
// - We shouldn't. This doesn't have anything to do with stores.
|
|
|
|
|
// Should we confirm the user?
|
|
|
|
|
// - Nope. Users should be grown-ass adults who take responsibilty of their actions.
|
|
|
|
|
// But one of my users is my new born kid!
|
|
|
|
|
// - Then? Kids will fuck things up anyway.
|
2016-11-26 03:25:35 +00:00
|
|
|
|
http.delete('lastfm/disconnect', {}, forceReloadWindow)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-13 04:42:28 +00:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="sass">
|
2016-06-25 16:05:24 +00:00
|
|
|
|
@import "../../../../sass/partials/_vars.scss";
|
|
|
|
|
@import "../../../../sass/partials/_mixins.scss";
|
|
|
|
|
|
|
|
|
|
#profileWrapper {
|
|
|
|
|
input {
|
|
|
|
|
&[type="text"], &[type="email"], &[type="password"] {
|
|
|
|
|
width: 192px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.error {
|
|
|
|
|
// Chrome won't give up its autofill style, so this is kind of a hack.
|
|
|
|
|
box-shadow: 0 0 0px 1000px #ff867a inset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.change-pwd {
|
|
|
|
|
margin-top: 24px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status {
|
|
|
|
|
margin-left: 8px;
|
|
|
|
|
color: $colorGreen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.preferences {
|
|
|
|
|
margin-top: 32px;
|
|
|
|
|
border-top: 1px solid $color2ndBgr;
|
|
|
|
|
|
|
|
|
|
label {
|
|
|
|
|
font-size: $fontSize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.lastfm {
|
|
|
|
|
border-top: 1px solid $color2ndBgr;
|
|
|
|
|
color: $color2ndText;
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
padding-top: 16px;
|
|
|
|
|
|
|
|
|
|
a {
|
|
|
|
|
color: $colorHighlight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.buttons {
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
|
|
|
|
.connect {
|
|
|
|
|
background: #d31f27; // Last.fm color yo!
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.disconnect {
|
|
|
|
|
background: $colorGrey; // Our color yo!
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media only screen and (max-width : 667px) {
|
|
|
|
|
input {
|
|
|
|
|
&[type="text"], &[type="email"], &[type="password"] {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 32px;
|
|
|
|
|
}
|
2015-12-13 04:42:28 +00:00
|
|
|
|
}
|
2016-06-25 16:05:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-13 04:42:28 +00:00
|
|
|
|
</style>
|