Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search: Add hashtags to results #3780

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
>
<ft-list-lazy-wrapper
v-for="(result, index) in data"
:key="`${result.type}-${result.videoId || result.playlistId || result.postId || result.id || result.authorId}-${index}`"
:key="`${result.type}-${result.videoId || result.playlistId || result.postId || result.id || result.authorId || result.title}-${index}`"
appearance="result"
:data="result"
:first-screen="index < 16"
Expand Down
44 changes: 44 additions & 0 deletions src/renderer/components/ft-list-hashtag/ft-list-hashtag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { defineComponent } from 'vue'
import { formatNumber } from '../../helpers/utils'

export default defineComponent({
name: 'FtListHashtag',
props: {
data: {
type: Object,
required: true
},
appearance: {
type: String,
required: true
}
},
data: function () {
return {
title: '',
url: '',
channelCount: 0,
parsedChannelCount: '',
videoCount: 0,
parsedVideosCount: ''
}
},
computed: {
listType: function () {
return this.$store.getters.getListType
}
},
created: function () {
this.parseData()
},
methods: {
parseData: function () {
this.title = this.data.title
this.channelCount = this.data.channelCount
this.parsedChannelCount = formatNumber(this.channelCount)
this.videoCount = this.data.videoCount
this.parsedVideosCount = formatNumber(this.videoCount)
this.url = this.data.url ?? `hashtag/${encodeURIComponent(this.data.title.substring(1))}`
}
}
})
6 changes: 6 additions & 0 deletions src/renderer/components/ft-list-hashtag/ft-list-hashtag.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@use '../../scss-partials/_ft-list-item';

.hashtagImage {
color: var(--primary-text-color);
font-size: 150px;
}
51 changes: 51 additions & 0 deletions src/renderer/components/ft-list-hashtag/ft-list-hashtag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div
class="ft-list-hashtag ft-list-item"
:class="{
list: listType === 'list',
grid: listType === 'grid',
[appearance]: true
}"
>
<div class="channelThumbnail">
<router-link
tabindex="-1"
aria-hidden="true"
:to="url"
>
<font-awesome-icon
class="hashtagImage"
:icon="['fas', 'hashtag']"
/>
</router-link>
</div>
<div class="info">
<router-link
class="title"
:to="url"
>
<h3 class="h3Title">
{{ title }}
</h3>
</router-link>
<div class="infoLine">
<span
v-if="channelCount"
class="channelCount"
>
{{ $tc('Global.Counts.Channel Count', channelCount, {count: parsedChannelCount}) }}
</span>
<span
v-if="videoCount"
class="videoCount"
>
<template v-if="channelCount"> • </template>
{{ $tc('Global.Counts.Video Count', videoCount, {count: parsedVideosCount}) }}
</span>
</div>
</div>
</div>
</template>

<script src="./ft-list-hashtag.js" />
<style scoped lang="scss" src="./ft-list-hashtag.scss" />
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import FtListVideo from '../ft-list-video/ft-list-video.vue'
import FtListChannel from '../ft-list-channel/ft-list-channel.vue'
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
import FtCommunityPost from '../ft-community-post/ft-community-post.vue'
import FtListHashtag from '../ft-list-hashtag/ft-list-hashtag.vue'

export default defineComponent({
name: 'FtListLazyWrapper',
components: {
'ft-list-video': FtListVideo,
'ft-list-channel': FtListChannel,
'ft-list-playlist': FtListPlaylist,
'ft-community-post': FtCommunityPost
'ft-community-post': FtCommunityPost,
'ft-list-hashtag': FtListHashtag,
},
props: {
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
:appearance="appearance"
:data="data"
/>
<ft-list-hashtag
v-else-if="data.type === 'hashtag'"
:appearance="appearance"
:data="data"
/>
</template>
</div>
</template>
Expand Down
14 changes: 13 additions & 1 deletion src/renderer/helpers/api/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ function handleSearchResponse(response) {

const results = response.results
.filter((item) => {
return item.type === 'Video' || item.type === 'Channel' || item.type === 'Playlist'
return item.type === 'Video' || item.type === 'Channel' || item.type === 'Playlist' || item.type === 'HashtagTile'
})
.map((item) => parseListItem(item))

Expand Down Expand Up @@ -580,6 +580,18 @@ function parseListItem(item) {
descriptionShort: channel.description_snippet.text
}
}
case 'HashtagTile': {
/** @type {import('youtubei.js').YTNodes.HashtagTile} */
const hashtag = item

return {
type: 'hashtag',
title: hashtag.hashtag.text,
videoCount: hashtag.hashtag_video_count.isEmpty() ? null : parseLocalSubscriberCount(hashtag.hashtag_video_count.text),
channelCount: hashtag.hashtag_channel_count.isEmpty() ? null : parseLocalSubscriberCount(hashtag.hashtag_channel_count.text),
url: hashtag.endpoint.metadata.url
ChunkyProgrammer marked this conversation as resolved.
Show resolved Hide resolved
}
}
case 'Playlist': {
return parseLocalListPlaylist(item)
}
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
faFilter,
faFire,
faGlobe,
faHashtag,
faHeart,
faHistory,
faInfoCircle,
Expand Down Expand Up @@ -105,6 +106,7 @@ library.add(
faFilter,
faFire,
faGlobe,
faHashtag,
faHeart,
faHistory,
faInfoCircle,
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/views/Search/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export default defineComponent({
this.apiUsed = 'invidious'

const returnData = result.filter((item) => {
return item.type === 'video' || item.type === 'channel' || item.type === 'playlist'
return item.type === 'video' || item.type === 'channel' || item.type === 'playlist' || item.type === 'hashtag'
})

if (this.searchPage !== 1) {
Expand Down
3 changes: 3 additions & 0 deletions static/locales/en-US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ Global:
Videos: Videos
Shorts: Shorts
Live: Live
Counts:
Video Count: 1 video | {count} videos
Channel Count: 1 channel | {count} channels

# Search Bar
Search / Go to URL: Search / Go to URL
Expand Down