diff --git a/package.json b/package.json index 5fc1d46dc..90bb41fea 100644 --- a/package.json +++ b/package.json @@ -74,8 +74,9 @@ "vue-i18n": "^8.28.2", "vue-observe-visibility": "^1.0.0", "vue-router": "^3.6.5", + "vue-tiny-slider": "^0.1.39", "vuex": "^3.6.2", - "youtubei.js": "^3.1.0" + "youtubei.js": "^3.1.1" }, "devDependencies": { "@babel/core": "^7.21.0", diff --git a/src/renderer/components/ft-community-post/ft-community-post.js b/src/renderer/components/ft-community-post/ft-community-post.js new file mode 100644 index 000000000..1620ce453 --- /dev/null +++ b/src/renderer/components/ft-community-post/ft-community-post.js @@ -0,0 +1,127 @@ +import Vue from 'vue' +import FtListVideo from '../ft-list-video/ft-list-video.vue' +import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue' + +import autolinker from 'autolinker' +import VueTinySlider from 'vue-tiny-slider' + +import { + toLocalePublicationString +} from '../../helpers/utils' +import { youtubeImageUrlToInvidious } from '../../helpers/api/invidious' + +import 'tiny-slider/dist/tiny-slider.css' + +export default Vue.extend({ + name: 'FtCommunityPost', + components: { + 'ft-list-playlist': FtListPlaylist, + 'ft-list-video': FtListVideo, + 'tiny-slider': VueTinySlider + }, + props: { + data: { + type: Object, + required: true + }, + playlistId: { + type: String, + default: null + }, + forceListType: { + type: String, + default: null + }, + appearance: { + type: String, + required: true + } + }, + data: function () { + return { + postText: '', + postId: '', + authorThumbnails: null, + publishedText: '', + voteCount: '', + postContent: '', + commentCount: '', + isLoading: true, + author: '' + } + }, + computed: { + tinySliderOptions: function() { + return { + items: 1, + arrowKeys: false, + controls: false, + autoplay: false, + slideBy: 'page', + navPosition: 'bottom' + } + }, + + listType: function () { + return this.$store.getters.getListType + } + }, + mounted: function () { + this.parseVideoData() + }, + methods: { + parseVideoData: function () { + if ('backstagePostThreadRenderer' in this.data) { + this.postText = 'Shared post' + this.type = 'text' + let authorThumbnails = ['', 'https://yt3.ggpht.com/ytc/AAUvwnjm-0qglHJkAHqLFsCQQO97G7cCNDuDLldsrn25Lg=s88-c-k-c0x00ffffff-no-rj'] + if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') { + authorThumbnails = authorThumbnails.map(thumbnail => { + thumbnail.url = youtubeImageUrlToInvidious(thumbnail.url) + return thumbnail + }) + } + this.authorThumbnails = authorThumbnails + return + } + this.postText = autolinker.link(this.data.postText) + let authorThumbnails = this.data.authorThumbnails + if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') { + authorThumbnails = authorThumbnails.map(thumbnail => { + thumbnail.url = youtubeImageUrlToInvidious(thumbnail.url) + return thumbnail + }) + } else { + authorThumbnails = authorThumbnails.map(thumbnail => { + if (thumbnail.url.startsWith('//')) { + thumbnail.url = 'https:' + thumbnail.url + } + return thumbnail + }) + } + this.authorThumbnails = authorThumbnails + this.postContent = this.data.postContent + this.postId = this.data.postId + this.publishedText = toLocalePublicationString({ + publishText: this.data.publishedText, + isLive: this.isLive, + isUpcoming: this.isUpcoming, + isRSS: this.data.isRSS + }) + this.voteCount = this.data.voteCount + this.commentCount = this.data.commentCount + this.type = (this.data.postContent !== null && this.data.postContent !== undefined) ? this.data.postContent.type : 'text' + this.author = this.data.author + this.isLoading = false + }, + + getBestQualityImage(imageArray) { + const imageArrayCopy = Array.from(imageArray) + imageArrayCopy.sort((a, b) => { + return Number.parseInt(b.width) - Number.parseInt(a.width) + }) + + return imageArrayCopy.at(0)?.url ?? '' + } + } +}) diff --git a/src/renderer/components/ft-community-post/ft-community-post.scss b/src/renderer/components/ft-community-post/ft-community-post.scss new file mode 100644 index 000000000..d9dcf438b --- /dev/null +++ b/src/renderer/components/ft-community-post/ft-community-post.scss @@ -0,0 +1,149 @@ +/* stylelint-disable property-no-vendor-prefix */ +@use '../../scss-partials/_ft-list-item'; + +.outside { + margin: auto; + width: 40%; +} + +.circle { + background-color: transparent; + border-radius: 50%; + border-style: solid; + border-width: 2px; + display: block; + float: left; + height: 10px; + left: 5px; + position: relative; + top: 8px; + width: 10px; +} + +.poll-text { + border-radius: 5px; + border-style: solid; + border-width: 2px; + padding: 5px 25px; +} + +.poll-option { + padding-bottom: 10px; +} + +.communityImage { + height: 100%; + width: 100%; +} + +.communityThumbnail { + -webkit-border-radius: 50%; + border-radius: 50%; + height: 55px; + margin-right: 5px; + width: 55px; +} + +.author-div { + display: flex; + + .authorName { + font-size: 15px; + font-weight: bold; + margin: 5px 6px 0 5px; + } + + .publishedText { + font-size: 15px; + margin: 5px 6px 0 5px; + } +} + +.bottomSection { + color: var(--tertiary-text-color); + display: block; + flex-direction: column; + font-size: 15px; + margin-top: 4px; + max-width: 210px; + text-align: left; + + @media screen and (max-width: 680px) { + margin-left: 0; + text-align: left; + } + + .likeBar { + border-radius: 4px; + height: 8px; + margin-bottom: 4px; + } + + .likeCount { + margin-left: 5px; + margin-right: 6px; + } + + .dislikeCount { + margin-right: 10px; + } +} + +.playlistWrapper { + display: flex; + + .videoThumbnail { + display: flex; + margin-bottom: auto; + margin-top: auto; + position: relative; + width: fit-content; + + .thumbnailImage { + display: block; + height: auto; + max-width: 100%; + width: auto; + } + } + + .playlistText { + margin-left: 10px; + width: 50%; + word-wrap: break-word; + + .playlistAuthor { + font-size: small; + + .playlistVideoCount { + font-size: smaller; + } + } + + .playlistTitle { + color: var(--primary-text-color); + } + + .playlistPreviewVideos { + color: var(--primary-text-color); + display: flex; + font-size: small; + padding-top: 10px; + text-decoration-line: none; + width: 100%; + } + + .playlistPreviewVideoTitle { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; + } + } +} + +.ft-list-item.grid { + min-height: 0 !important; + padding-bottom: 20px; +} diff --git a/src/renderer/components/ft-community-post/ft-community-post.vue b/src/renderer/components/ft-community-post/ft-community-post.vue new file mode 100644 index 000000000..e8e88b4bb --- /dev/null +++ b/src/renderer/components/ft-community-post/ft-community-post.vue @@ -0,0 +1,123 @@ + + +