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:
Ira ¯\_(ツ)_/¯ 2021-03-06 18:00:52 +00:00 committed by GitHub
parent 3b75a97859
commit f06af7da83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 43 deletions

View File

@ -1,5 +0,0 @@
.card {
width: 85%;
margin: 0 auto;
margin-bottom: 30px;
}

View File

@ -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;
}

View File

@ -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({

View File

@ -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" />

View File

@ -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 {

View File

@ -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"
/> />

View File

@ -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