Create Profile Edit Page

This commit is contained in:
Preston 2020-08-23 22:56:33 -04:00
parent b291cbf37b
commit 0a612ae0e7
16 changed files with 370 additions and 31 deletions

View File

@ -23,6 +23,10 @@ export default Vue.extend({
type: Boolean, type: Boolean,
default: false default: false
}, },
disabled: {
type: Boolean,
default: false
},
dataList: { dataList: {
type: Array, type: Array,
default: () => { return [] } default: () => { return [] }
@ -47,6 +51,11 @@ export default Vue.extend({
return `${this.id}_datalist` return `${this.id}_datalist`
} }
}, },
watch: {
value: function (val) {
this.inputData = val
}
},
mounted: function () { mounted: function () {
this.id = this._uid this.id = this._uid
this.inputData = this.value this.inputData = this.value

View File

@ -20,6 +20,7 @@
type="text" type="text"
:placeholder="placeholder" :placeholder="placeholder"
@input="e => handleInput(e.target.value)" @input="e => handleInput(e.target.value)"
:disabled="disabled"
> >
<font-awesome-icon <font-awesome-icon
v-if="showArrow" v-if="showArrow"

View File

@ -0,0 +1,41 @@
.bubblePadding {
width: 100px;
height: 115px;
padding: 10px;
cursor: pointer;
-webkit-transition: background 0.2s ease-out;
-moz-transition: background 0.2s ease-out;
-o-transition: background 0.2s ease-out;
transition: background 0.2s ease-out;
}
.bubblePadding:hover {
background-color: var(--side-nav-hover-color);
-moz-transition: background 0.2s ease-in;
-o-transition: background 0.2s ease-in;
transition: background 0.2s ease-in;
}
.bubble {
width: 50px;
height: 50px;
margin-top: 20px;
margin-bottom: 5px;
margin-left: 25px;
border-radius: 200px 200px 200px 200px;
-webkit-border-radius: 200px 200px 200px 200px;
}
.initial {
font-size: 25px;
text-align: center;
position: relative;
top: 12px;
}
.profileName {
font-size: 13px;
height: 60px;
overflow: hidden;
text-align: center;
}

View File

@ -0,0 +1,35 @@
import Vue from 'vue'
export default Vue.extend({
name: 'FtProfileBubble',
props: {
profileName: {
type: String,
required: true
},
profileId: {
type: String,
required: true
},
backgroundColor: {
type: String,
required: true
},
textColor: {
type: String,
required: true
}
},
computed: {
profileInitial: function () {
return this.profileName.slice(0, 1).toUpperCase()
}
},
methods: {
goToProfile: function () {
this.$router.push({
path: `/settings/profile/edit/${this.profileId}`
})
}
}
})

View File

@ -0,0 +1,21 @@
<template>
<div
class="bubblePadding"
@click="goToProfile"
>
<div
class="bubble"
:style="{ background: backgroundColor, color: textColor }"
>
<p class="initial">
{{ profileInitial }}
</p>
</div>
<div class="profileName">
{{ profileName }}
</div>
</div>
</template>
<script src="./ft-profile-bubble.js" />
<style scoped src="./ft-profile-bubble.css" />

View File

@ -30,6 +30,7 @@
:label="subscribedText" :label="subscribedText"
class="subscribeButton" class="subscribeButton"
background-color="var(--primary-color)" background-color="var(--primary-color)"
text-color="var(--text-with-main-color)"
@click="handleSubscription" @click="handleSubscription"
/> />
</div> </div>

View File

@ -44,6 +44,7 @@ const router = new Router({
}, },
{ {
path: '/settings/profile/new', path: '/settings/profile/new',
name: 'newProfile',
meta: { meta: {
title: 'New Profile', title: 'New Profile',
icon: 'fa-home' icon: 'fa-home'
@ -52,6 +53,7 @@ const router = new Router({
}, },
{ {
path: '/settings/profile/edit/:id', path: '/settings/profile/edit/:id',
name: 'editProfile',
meta: { meta: {
title: 'Edit Profile', title: 'Edit Profile',
icon: 'fa-home' icon: 'fa-home'

View File

@ -31,7 +31,7 @@ const state = {
const getters = { const getters = {
getProfileList: () => { getProfileList: () => {
return state.historyCache return state.profileList
} }
} }
@ -39,6 +39,7 @@ const actions = {
grabAllProfiles ({ dispatch, commit }, defaultName = null) { grabAllProfiles ({ dispatch, commit }, defaultName = null) {
profileDb.find({}, (err, results) => { profileDb.find({}, (err, results) => {
if (!err) { if (!err) {
console.log(results)
if (results.length === 0) { if (results.length === 0) {
dispatch('createDefaultProfile', defaultName) dispatch('createDefaultProfile', defaultName)
} else { } else {
@ -48,6 +49,17 @@ const actions = {
}) })
}, },
grabProfileInfo (_, profileId) {
return new Promise((resolve, reject) => {
console.log(profileId)
profileDb.findOne({ _id: profileId }, (err, results) => {
if (!err) {
resolve(results)
}
})
})
},
async createDefaultProfile ({ dispatch }, defaultName) { async createDefaultProfile ({ dispatch }, defaultName) {
const randomColor = await dispatch('getRandomColor') const randomColor = await dispatch('getRandomColor')
const textColor = await dispatch('calculateColorLuminance', randomColor) const textColor = await dispatch('calculateColorLuminance', randomColor)
@ -59,7 +71,6 @@ const actions = {
subscriptions: [] subscriptions: []
} }
console.log(defaultProfile) console.log(defaultProfile)
return
profileDb.update({ _id: 'allChannels' }, defaultProfile, { upsert: true }, (err, numReplaced) => { profileDb.update({ _id: 'allChannels' }, defaultProfile, { upsert: true }, (err, numReplaced) => {
if (!err) { if (!err) {
dispatch('grabAllProfiles') dispatch('grabAllProfiles')
@ -68,23 +79,23 @@ const actions = {
}, },
updateProfile ({ dispatch }, profile) { updateProfile ({ dispatch }, profile) {
profileDb.update({ name: profile.name }, profile, { upsert: true }, (err, numReplaced) => { profileDb.update({ _id: profile._id }, profile, { upsert: true }, (err, numReplaced) => {
if (!err) { if (!err) {
dispatch('grabAllProfiles') dispatch('grabAllProfiles')
} }
}) })
}, },
removeFromHistory ({ dispatch }, videoId) { insertProfile ({ dispatch }, profile) {
historyDb.remove({ videoId: videoId }, (err, numReplaced) => { profileDb.insert(profile, (err, newDocs) => {
if (!err) { if (!err) {
dispatch('grabHistory') dispatch('grabAllProfiles')
} }
}) })
}, },
updateWatchProgress ({ dispatch }, videoData) { removeProfile ({ dispatch }, videoId) {
historyDb.update({ videoId: videoData.videoId }, { $set: { watchProgress: videoData.watchProgress } }, { upsert: true }, (err, numReplaced) => { profileDb.remove({ videoId: videoId }, (err, numReplaced) => {
if (!err) { if (!err) {
dispatch('grabHistory') dispatch('grabHistory')
} }
@ -93,8 +104,8 @@ const actions = {
} }
const mutations = { const mutations = {
setHistoryCache (state, historyCache) { setProfileList (state, profileList) {
state.historyCache = historyCache state.profileList = profileList
} }
} }

View File

@ -36,6 +36,7 @@ const state = {
listType: 'grid', listType: 'grid',
thumbnailPreference: '', thumbnailPreference: '',
invidiousInstance: 'https://invidio.us', invidiousInstance: 'https://invidio.us',
defaultProfile: 'allChannels',
barColor: false, barColor: false,
enableSearchSuggestions: true, enableSearchSuggestions: true,
rememberHistory: true, rememberHistory: true,
@ -56,9 +57,7 @@ const state = {
debugMode: false, debugMode: false,
disctractionFreeMode: false, disctractionFreeMode: false,
hideWatchedSubs: false, hideWatchedSubs: false,
usingElectron: true, usingElectron: true
profileList: [{ name: 'All Channels', color: '#304FFE' }],
defaultProfile: 'All Channels'
} }
const getters = { const getters = {
@ -102,6 +101,10 @@ const getters = {
return state.invidiousInstance return state.invidiousInstance
}, },
getDefaultProfile: () => {
return state.defaultProfile
},
getRememberHistory: () => { getRememberHistory: () => {
return state.rememberHistory return state.rememberHistory
}, },
@ -176,6 +179,9 @@ const actions = {
case 'backendFallback': case 'backendFallback':
commit('setBackendFallback', result.value) commit('setBackendFallback', result.value)
break break
case 'defaultProfile':
commit('setDefaultProfile', result.value)
break
case 'checkForUpdates': case 'checkForUpdates':
commit('setCheckForUpdates', result.value) commit('setCheckForUpdates', result.value)
break break
@ -255,6 +261,14 @@ const actions = {
}) })
}, },
updateDefaultProfile ({ commit }, defaultProfile) {
settingsDb.update({ _id: 'defaultProfile' }, { _id: 'defaultProfile', value: defaultProfile }, { upsert: true }, (err, numReplaced) => {
if (!err) {
commit('setDefaultProfile', defaultProfile)
}
})
},
updateBackendFallback ({ commit }, backendFallback) { updateBackendFallback ({ commit }, backendFallback) {
settingsDb.update({ _id: 'backendFallback' }, { _id: 'backendFallback', value: backendFallback }, { upsert: true }, (err, numReplaced) => { settingsDb.update({ _id: 'backendFallback' }, { _id: 'backendFallback', value: backendFallback }, { upsert: true }, (err, numReplaced) => {
if (!err) { if (!err) {
@ -448,6 +462,9 @@ const mutations = {
setCurrentTheme (state, currentTheme) { setCurrentTheme (state, currentTheme) {
state.barColor = currentTheme state.barColor = currentTheme
}, },
setDefaultProfile (state, defaultProfile) {
state.defaultProfile = defaultProfile
},
setBackendFallback (state, backendFallback) { setBackendFallback (state, backendFallback) {
state.backendFallback = backendFallback state.backendFallback = backendFallback
}, },
@ -537,9 +554,6 @@ const mutations = {
}, },
setProfileList (state, profileList) { setProfileList (state, profileList) {
state.profileList = profileList state.profileList = profileList
},
setDefaultProfile (state, defaultProfile) {
state.defaultProfile = defaultProfile
} }
} }

View File

@ -72,6 +72,10 @@ const getters = {
getSearchSettings () { getSearchSettings () {
return state.searchSettings return state.searchSettings
},
getColorValues () {
return state.colorValues
} }
} }

View File

@ -8,6 +8,30 @@
color: var(--tertiary-text-color); color: var(--tertiary-text-color);
} }
.profileName {
width: 400px;
}
.bottomMargin {
margin-bottom: 30px;
}
.colorOption {
width: 100px;
height: 100px;
margin: 10px;
cursor: pointer;
border-radius: 200px 200px 200px 200px;
-webkit-border-radius: 200px 200px 200px 200px;
}
.initial {
font-size: 50px;
text-align: center;
position: relative;
bottom: 27px;
}
@media only screen and (max-width: 680px) { @media only screen and (max-width: 680px) {
.card { .card {
width: 90%; width: 90%;

View File

@ -1,15 +1,92 @@
import Vue from 'vue' import Vue from 'vue'
import { mapActions } from 'vuex'
import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtCard from '../../components/ft-card/ft-card.vue' import FtCard from '../../components/ft-card/ft-card.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue' import FtInput from '../../components/ft-input/ft-input.vue'
import FtButton from '../../components/ft-button/ft-button.vue'
export default Vue.extend({ export default Vue.extend({
name: 'ProfileEdit', name: 'ProfileEdit',
components: { components: {
'ft-loader': FtLoader,
'ft-card': FtCard, 'ft-card': FtCard,
'ft-flex-box': FtFlexBox, 'ft-flex-box': FtFlexBox,
'ft-element-list': FtElementList 'ft-input': FtInput,
'ft-button': FtButton
},
data: function () {
return {
isLoading: false,
isNew: false,
profileId: '',
profileName: '',
profileBgColor: '',
profileTextColor: '',
profileSubscriptions: []
}
},
computed: {
colorValues: function () {
return this.$store.getters.getColorValues
},
profileInitial: function () {
return this.profileName.slice(0, 1).toUpperCase()
}
},
watch: {
profileBgColor: async function (val) {
this.profileTextColor = await this.calculateColorLuminance(val)
}
}, },
mounted: function () { mounted: function () {
this.isLoading = true
const profileType = this.$route.name
if (profileType === 'newProfile') {
this.isNew = true
} else {
this.isNew = false
this.profileId = this.$route.params.id
console.log(this.profileId)
console.log(this.$route.name)
this.grabProfileInfo(this.profileId).then((profile) => {
console.log(profile)
this.profileName = profile.name
this.profileBgColor = profile.bgColor
this.profileTextColor = profile.textColor
this.profileSubscriptions = profile.subscriptions
this.isLoading = false
})
}
},
methods: {
saveProfile: function () {
const profile = {
name: this.profileName,
bgColor: this.profileBgColor,
textColor: this.profileTextColor,
subscriptions: this.profileSubscriptions
}
if (!this.isNew) {
profile._id = this.profileId
}
console.log(profile)
this.updateProfile(profile)
this.showToast({
message: 'Profile has been updated'
})
},
...mapActions([
'showToast',
'grabProfileInfo',
'updateProfile',
'calculateColorLuminance'
])
} }
}) })

View File

@ -1,14 +1,91 @@
<template> <template>
<div> <div>
<ft-loader
v-if="isLoading"
:fullscreen="true"
/>
<div
v-else
>
<ft-card class="card"> <ft-card class="card">
<h3>{{ $t("Subscriptions.Subscriptions") }}</h3> <h2>{{ $t("Profile.Edit Profile") }}</h2>
<ft-flex-box> <ft-flex-box>
<p class="message"> <ft-input
{{ $t("This part of the app is not ready yet. Come back later when progress has been made.") }} class="profileName"
placeholder="Profile Name"
:value="profileName"
:show-arrow="false"
@input="e => profileName = e"
/>
</ft-flex-box>
<h3>{{ $t("Profile.Color Picker") }}</h3>
<ft-flex-box
class="bottomMargin"
>
<div
v-for="(color, index) in colorValues"
:key="index"
class="colorOption"
:style="{ background: color }"
@click="profileBgColor = color"
/>
</ft-flex-box>
<ft-flex-box
class="bottomMargin"
>
<div>
<label for="colorPicker">{{ $t("Profile.Custom Color") }}</label>
<input
id="colorPicker"
type="color"
v-model="profileBgColor"
/>
</div>
</ft-flex-box>
<ft-flex-box>
<ft-input
class="profileName"
placeholder=""
:value="profileBgColor"
:show-arrow="false"
:disabled="true"
/>
</ft-flex-box>
<h3>{{ $t("Profile.Profile Preview") }}</h3>
<ft-flex-box
class="bottomMargin"
>
<div
class="colorOption"
:style="{ background: profileBgColor, color: profileTextColor }"
style="cursor: default"
>
<p
class="initial"
>
{{ profileInitial }}
</p> </p>
</div>
</ft-flex-box>
<ft-flex-box>
<ft-button
:label="$t('Profile.Update Profile')"
@click="saveProfile"
/>
<ft-button
:label="$t('Profile.Make Default Profile')"
@click="saveProfile"
/>
<ft-button
:label="$t('Profile.Delete Profile')"
text-color="var(--text-with-main-color)"
background-color="var(--primary-color)"
@click="saveProfile"
/>
</ft-flex-box> </ft-flex-box>
</ft-card> </ft-card>
</div> </div>
</div>
</template> </template>
<script src="./ProfileEdit.js" /> <script src="./ProfileEdit.js" />

View File

@ -1,15 +1,21 @@
import Vue from 'vue' import Vue from 'vue'
import FtCard from '../../components/ft-card/ft-card.vue' import FtCard from '../../components/ft-card/ft-card.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue' import FtProfileBubble from '../../components/ft-profile-bubble/ft-profile-bubble.vue'
export default Vue.extend({ export default Vue.extend({
name: 'ProfileSettings', name: 'ProfileSettings',
components: { components: {
'ft-card': FtCard, 'ft-card': FtCard,
'ft-flex-box': FtFlexBox, 'ft-flex-box': FtFlexBox,
'ft-element-list': FtElementList 'ft-profile-bubble': FtProfileBubble
},
computed: {
profileList: function () {
return this.$store.getters.getProfileList
}
}, },
mounted: function () { mounted: function () {
console.log(this.profileList)
} }
}) })

View File

@ -3,9 +3,14 @@
<ft-card class="card"> <ft-card class="card">
<h3>{{ $t("Profile.Profile Manager") }}</h3> <h3>{{ $t("Profile.Profile Manager") }}</h3>
<ft-flex-box> <ft-flex-box>
<p class="message"> <ft-profile-bubble
{{ $t("This part of the app is not ready yet. Come back later when progress has been made.") }} v-for="(profile, index) in profileList"
</p> :key="index"
:profile-id="profile._id"
:profile-name="profile.name"
:background-color="profile.bgColor"
:text-color="profile.textColor"
/>
</ft-flex-box> </ft-flex-box>
</ft-card> </ft-card>
</div> </div>

View File

@ -249,6 +249,17 @@ About:
Profile: Profile:
All Channels: All Channels All Channels: All Channels
Profile Manager: Profile Manager Profile Manager: Profile Manager
Create New Profile: Create New Profile
Edit Profile: Edit Profile
Color Picker: Color Picker
Custom Color: Custom Color
Profile Preview: Profile Preview
Create Profile: Create Profile
Update Profile: Update Profile
Make Default Profile: Make Default Profile
Delete Profile: Delete Profile
Are you sure you want to delete this profile?: Are you sure you want to delete this profile?
All subscriptions will also be deleted.: All subscriptions will also be deleted.
#On Channel Page #On Channel Page
Channel: Channel:
Subscriber: Subscriber Subscriber: Subscriber