Enable profile based channel filtering (#1013)
* Delete FtProfileAllChannelsList component * Replace FtProfileAllChannelsList component with new filtered variant * Add new locale for profile filter label * Add FtProfileFilterChannelsList vue component with ft-select addition * Add FtProfileFilterChannelsList script with profile filtering support * Add css modifications to new FtProfileFilterChannelsList component
This commit is contained in:
parent
3b75a97859
commit
f06af7da83
|
@ -1,5 +0,0 @@
|
||||||
.card {
|
|
||||||
width: 85%;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
.card {
|
||||||
|
width: 85%;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .select-label {
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .select {
|
||||||
|
text-align-last: center;
|
||||||
|
}
|
|
@ -6,15 +6,17 @@ import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
|
||||||
import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue'
|
import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue'
|
||||||
import FtButton from '../../components/ft-button/ft-button.vue'
|
import FtButton from '../../components/ft-button/ft-button.vue'
|
||||||
import FtPrompt from '../../components/ft-prompt/ft-prompt.vue'
|
import FtPrompt from '../../components/ft-prompt/ft-prompt.vue'
|
||||||
|
import FtSelect from '../ft-select/ft-select.vue'
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'FtProfileAllChannelsList',
|
name: 'FtProfileFilterChannelsList',
|
||||||
components: {
|
components: {
|
||||||
'ft-card': FtCard,
|
'ft-card': FtCard,
|
||||||
'ft-flex-box': FtFlexBox,
|
'ft-flex-box': FtFlexBox,
|
||||||
'ft-channel-bubble': FtChannelBubble,
|
'ft-channel-bubble': FtChannelBubble,
|
||||||
'ft-button': FtButton,
|
'ft-button': FtButton,
|
||||||
'ft-prompt': FtPrompt
|
'ft-prompt': FtPrompt,
|
||||||
|
'ft-select': FtSelect
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
profile: {
|
profile: {
|
||||||
|
@ -25,7 +27,8 @@ export default Vue.extend({
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
channels: [],
|
channels: [],
|
||||||
selectedLength: 0
|
selectedLength: 0,
|
||||||
|
filteredProfileIndex: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -38,44 +41,21 @@ export default Vue.extend({
|
||||||
profileList: function () {
|
profileList: function () {
|
||||||
return this.$store.getters.getProfileList
|
return this.$store.getters.getProfileList
|
||||||
},
|
},
|
||||||
|
profileNameList: function () {
|
||||||
|
return this.profileList.flatMap((profile) => profile.name !== this.profile.name ? [profile.name] : [])
|
||||||
|
},
|
||||||
selectedText: function () {
|
selectedText: function () {
|
||||||
const localeText = this.$t('Profile.$ selected')
|
const localeText = this.$t('Profile.$ selected')
|
||||||
return localeText.replace('$', this.selectedLength)
|
return localeText.replace('$', this.selectedLength)
|
||||||
},
|
|
||||||
primaryProfile: function () {
|
|
||||||
return JSON.parse(JSON.stringify(this.profileList[0]))
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
profile: function () {
|
profile: 'updateChannelList',
|
||||||
this.channels = JSON.parse(JSON.stringify(this.primaryProfile.subscriptions)).sort((a, b) => {
|
filteredProfileIndex: 'updateChannelList'
|
||||||
const nameA = a.name.toLowerCase()
|
|
||||||
const nameB = b.name.toLowerCase()
|
|
||||||
if (nameA < nameB) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if (nameA > nameB) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}).filter((channel) => {
|
|
||||||
const index = this.profile.subscriptions.findIndex((sub) => {
|
|
||||||
return sub.id === channel.id
|
|
||||||
})
|
|
||||||
|
|
||||||
return index === -1
|
|
||||||
}).map((channel) => {
|
|
||||||
if (this.backendPreference === 'invidious') {
|
|
||||||
channel.thumbnail = channel.thumbnail.replace('https://yt3.ggpht.com', `${this.invidiousInstance}/ggpht/`)
|
|
||||||
}
|
|
||||||
channel.selected = false
|
|
||||||
return channel
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
if (typeof this.profile.subscriptions !== 'undefined') {
|
if (typeof this.profile.subscriptions !== 'undefined') {
|
||||||
this.channels = JSON.parse(JSON.stringify(this.profileList[0].subscriptions)).sort((a, b) => {
|
this.channels = JSON.parse(JSON.stringify(this.profileList[this.filteredProfileIndex].subscriptions)).sort((a, b) => {
|
||||||
const nameA = a.name.toLowerCase()
|
const nameA = a.name.toLowerCase()
|
||||||
const nameB = b.name.toLowerCase()
|
const nameB = b.name.toLowerCase()
|
||||||
if (nameA < nameB) {
|
if (nameA < nameB) {
|
||||||
|
@ -101,6 +81,32 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
updateChannelList () {
|
||||||
|
this.channels = JSON.parse(JSON.stringify(this.profileList[this.filteredProfileIndex].subscriptions)).sort((a, b) => {
|
||||||
|
const nameA = a.name.toLowerCase()
|
||||||
|
const nameB = b.name.toLowerCase()
|
||||||
|
if (nameA < nameB) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if (nameA > nameB) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}).filter((channel) => {
|
||||||
|
const index = this.profile.subscriptions.findIndex((sub) => {
|
||||||
|
return sub.id === channel.id
|
||||||
|
})
|
||||||
|
|
||||||
|
return index === -1
|
||||||
|
}).map((channel) => {
|
||||||
|
if (this.backendPreference === 'invidious') {
|
||||||
|
channel.thumbnail = channel.thumbnail.replace('https://yt3.ggpht.com', `${this.invidiousInstance}/ggpht/`)
|
||||||
|
}
|
||||||
|
channel.selected = false
|
||||||
|
return channel
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
handleChannelClick: function (index) {
|
handleChannelClick: function (index) {
|
||||||
this.channels[index].selected = !this.channels[index].selected
|
this.channels[index].selected = !this.channels[index].selected
|
||||||
this.selectedLength = this.channels.filter((channel) => {
|
this.selectedLength = this.channels.filter((channel) => {
|
||||||
|
@ -108,6 +114,10 @@ export default Vue.extend({
|
||||||
}).length
|
}).length
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleProfileFilterChange: function (change) {
|
||||||
|
this.filteredProfileIndex = this.profileList.findIndex(profile => profile.name === change)
|
||||||
|
},
|
||||||
|
|
||||||
addChannelToProfile: function () {
|
addChannelToProfile: function () {
|
||||||
if (this.selectedLength === 0) {
|
if (this.selectedLength === 0) {
|
||||||
this.showToast({
|
this.showToast({
|
|
@ -4,7 +4,16 @@
|
||||||
<h2>
|
<h2>
|
||||||
{{ $t("Profile.Other Channels") }}
|
{{ $t("Profile.Other Channels") }}
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<ft-flex-box>
|
||||||
|
<ft-select
|
||||||
|
:placeholder="$t('Profile.Profile Filter')"
|
||||||
|
:value="profileNameList[0]"
|
||||||
|
:select-names="profileNameList"
|
||||||
|
:select-values="profileNameList"
|
||||||
|
@change="handleProfileFilterChange"
|
||||||
|
/>
|
||||||
|
</ft-flex-box>
|
||||||
|
<p class="selected">
|
||||||
{{ selectedText }}
|
{{ selectedText }}
|
||||||
</p>
|
</p>
|
||||||
<ft-flex-box>
|
<ft-flex-box>
|
||||||
|
@ -38,5 +47,5 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./ft-profile-all-channels-list.js" />
|
<script src="./ft-profile-filter-channels-list.js" />
|
||||||
<style scoped src="./ft-profile-all-channels-list.css" />
|
<style scoped src="./ft-profile-filter-channels-list.css" />
|
|
@ -3,7 +3,7 @@ import { mapActions } from 'vuex'
|
||||||
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
||||||
import FtProfileEdit from '../../components/ft-profile-edit/ft-profile-edit.vue'
|
import FtProfileEdit from '../../components/ft-profile-edit/ft-profile-edit.vue'
|
||||||
import FtProfileChannelList from '../../components/ft-profile-channel-list/ft-profile-channel-list.vue'
|
import FtProfileChannelList from '../../components/ft-profile-channel-list/ft-profile-channel-list.vue'
|
||||||
import FtProfileAllChannelsList from '../../components/ft-profile-all-channels-list/ft-profile-all-channels-list.vue'
|
import FtProfileFilterChannelsList from '../../components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.vue'
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'ProfileEdit',
|
name: 'ProfileEdit',
|
||||||
|
@ -11,7 +11,7 @@ export default Vue.extend({
|
||||||
'ft-loader': FtLoader,
|
'ft-loader': FtLoader,
|
||||||
'ft-profile-edit': FtProfileEdit,
|
'ft-profile-edit': FtProfileEdit,
|
||||||
'ft-profile-channel-list': FtProfileChannelList,
|
'ft-profile-channel-list': FtProfileChannelList,
|
||||||
'ft-profile-all-channels-list': FtProfileAllChannelsList
|
'ft-profile-filter-channels-list': FtProfileFilterChannelsList
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
:profile="profile"
|
:profile="profile"
|
||||||
:is-main-profile="isMainProfile"
|
:is-main-profile="isMainProfile"
|
||||||
/>
|
/>
|
||||||
<ft-profile-all-channels-list
|
<ft-profile-filter-channels-list
|
||||||
v-if="!isNew && !isMainProfile"
|
v-if="!isNew && !isMainProfile"
|
||||||
:profile="profile"
|
:profile="profile"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -307,6 +307,7 @@ About:
|
||||||
|
|
||||||
Profile:
|
Profile:
|
||||||
Profile Select: Profile Select
|
Profile Select: Profile Select
|
||||||
|
Profile Filter: Profile Filter
|
||||||
All Channels: All Channels
|
All Channels: All Channels
|
||||||
Profile Manager: Profile Manager
|
Profile Manager: Profile Manager
|
||||||
Create New Profile: Create New Profile
|
Create New Profile: Create New Profile
|
||||||
|
|
Loading…
Reference in New Issue