diff options
author | Devlin Junker <devlin.junker@gmail.com> | 2023-08-15 13:11:22 -0700 |
---|---|---|
committer | Benjamin Brahmer <info@b-brahmer.de> | 2023-08-22 08:34:39 +0200 |
commit | d14dbe3fb10aa0280063b66226347a0c12fb219c (patch) | |
tree | 9d585638c33faefec3285fb1d9ce1ccc9ca39e45 /src | |
parent | 41213ad4869ee22d15bf148509b0ddc7a538f1cb (diff) |
match style from current app
Signed-off-by: Devlin Junker <devlin.junker@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/FeedItem.vue | 232 | ||||
-rw-r--r-- | src/components/Sidebar.vue | 4 | ||||
-rw-r--r-- | src/components/Starred.vue | 9 | ||||
-rw-r--r-- | src/store/item.ts | 9 | ||||
-rw-r--r-- | src/types/MutationTypes.ts | 1 |
5 files changed, 237 insertions, 18 deletions
diff --git a/src/components/FeedItem.vue b/src/components/FeedItem.vue index 2a61c473d..841dc4585 100644 --- a/src/components/FeedItem.vue +++ b/src/components/FeedItem.vue @@ -1,24 +1,118 @@ <template> - <div class="feed-item-container" @click="expand()"> - <div class="feed-item-row" style="display: flex; padding: 5px 10px;"> - <div style="padding: 0px 5px;"> - <EarthIcon /> + <div class="feed-item-container"> + <div class="feed-item-row" @click="expand()"> + <div style="padding-right: 5px; display: flex; flex-direction: row; align-self: start;"> + <a class="external" + target="_blank" + rel="noreferrer" + :href="item.url" + :title="t('news', 'Open website')" + @click="markRead(item.id); $event.stopPropagation();"> + <EarthIcon /> + </a> + <RssIcon v-if="!getFeed(item.feedId).faviconLink" /> + <span v-if="getFeed(item.feedId).faviconLink" :style="{ 'backgroundImage': 'url(' + Content.getFeed(item.feedId).faviconLink + ')' }" /> </div> - <div style="flex-grow: 1; overflow: hidden; text-overflow: ellipsis;"> - <span style="text-overflow: ellipsis;" :style="{ 'white-space': !isExpanded ? 'nowrap' : 'normal' }"> + <div class="title-container" :class="{ 'unread': item.unread }"> + <span :style="{ 'white-space': !isExpanded ? 'nowrap' : 'normal' }" :dir="item.rtl && 'rtl'"> {{ item.title }} + <span v-if="!isExpanded" class="intro" v-html="item.intro" /> </span> </div> - <div class="button-container" style="display: flex; flex-direction: row; align-self: start;"> - <StarIcon :class="{'starred': item.starred }" /> - <Eye /> - <ShareVariant /> + <div class="date-container"> + <time class="date" :title="formatDate(item.pubDate*1000, 'yyyy-MM-dd HH:mm:ss')" :datetime="formatDate(item.pubDate*1000, 'yyyy-MM-ddTHH:mm:ssZ')"> + {{ getRelativeTimestamp(item.pubDate*1000) }} + </time> + </div> + <div class="button-container" @click="$event.stopPropagation()"> + <StarIcon :class="{'starred': item.starred }" @click="toggleStarred()" /> + <Eye :class="{ 'keep-unread': item.keepUnread }" @click="toggleKeepUnread()" /> + <NcActions :force-menu="true"> + <template #icon> + <ShareVariant /> + </template> + <NcActionButton> + <template #default> + <!-- TODO: --> TODO + </template> + <template #icon> + <ShareVariant /> + </template> + </NcActionButton> + </NcActions> </div> </div> <div v-if="isExpanded" style="padding: 5px 10px;"> - <div class="feed-item-author" v-if="item.author != undefined" v-html="item.author" /> - <div v-html="item.body" /> + <div class="article"> + <!--div class="heading only-in-expanded"> + <time class="date" :title="formatDate(item.pubDate*1000, 'yyyy-MM-dd HH:mm:ss')" :datetime="formatDate(item.pubDate*1000, 'yyyy-MM-ddTHH:mm:ssZ')"> + {{ getRelativeTimestamp(item.pubDate*1000) }} + </time> + <h1 :dir="item.rtl && 'rtl'"> + <a class="external" + target="_blank" + rel="noreferrer" + :href="item.url" + :title="item.title"> + {{ item.title }} + </a> + </h1> + </div--> + + <div class="subtitle" :dir="item.rtl && 'rtl'"> + <span v-show="item.author !== undefined" class="author"> + {{ t('news', 'by') }} {{ item.author }} + </span> + <span v-if="!item.sharedBy" class="source">{{ t('news', 'from') }} + <!-- TODO: Fix this --> + <a :href="`#/items/feeds/${item.feedId}/`"> + {{ getFeed(item.feedId).title }} + <img v-if="getFeed(item.feedId).faviconLink && isCompactView()" :src="getFeed(item.feedId).faviconLink" alt="favicon"> + </a> + </span> + <span v-if="item.sharedBy"> + <span v-if="item.author">-</span> + {{ t('news', 'shared by') }} + {{ item.sharedByDisplayName }} + </span> + </div> + + <div v-if="getMediaType(item.enclosureMime) == 'audio'" class="enclosure"> + <button @click="play(item)"> + {{ t('news', 'Play audio') }} + <!--?php p($l->t('Play audio')) ?--> + </button> + <a class="button" + :href="item.enclosureLink" + target="_blank" + rel="noreferrer"> + {{ t('news', 'Download audio') }} + <!--?php p($l->t('Download audio')) ? --> + </a> + </div> + <div v-if="getMediaType(item.enclosureMime) == 'video'" class="enclosure"> + <video controls + preload="none" + news-play-one + :src="item.enclosureLink" + :type="item.enclosureMime" /> + <a class="button" + :href="item.enclosureLink" + target="_blank" + rel="noreferrer"> + {{ t('news', 'Download video') }} + </a> + </div> + + <div v-if="item.mediaThumbnail" class="enclosure thumbnail"> + <a :href="item.enclosureLink"><img :src="item.mediaThumbnail" alt=""></a> + </div> + + <div v-if="item.mediaDescription" class="enclosure description" v-html="item.mediaDescription" /> + + <div class="body" :dir="item.rtl && 'rtl'" v-html="item.body" /> + </div> </div> </div> </template> @@ -27,7 +121,10 @@ import EarthIcon from 'vue-material-design-icons/Earth.vue' import StarIcon from 'vue-material-design-icons/Star.vue' import Eye from 'vue-material-design-icons/Eye.vue' +import RssIcon from 'vue-material-design-icons/Rss.vue' import ShareVariant from 'vue-material-design-icons/ShareVariant.vue' +import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' +import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' export default { name: 'FeedItem', @@ -36,6 +133,9 @@ export default { StarIcon, Eye, ShareVariant, + RssIcon, + NcActions, + NcActionButton, }, props: { item: { @@ -57,24 +157,90 @@ export default { expand() { this.expanded = !this.expanded }, + formatDate() { + return 'test' + }, + getRelativeTimestamp() { + return 'yesterday' + }, + getFeed(id) { + return {} + }, + getMediaType(mime) { + return false + }, + play(item) { + // TODO: implement this + }, + markRead() { + // TODO: implement this + }, + toggleKeepUnread() { + // TODO: implement this + }, + toggleStarred() { + // TODO: implement this + }, }, } </script> <style> - .feed-item-container, .feed-item-container * { - cursor: pointer; - } .feed-item-container { border-bottom: 1px solid #222; } + .feed-item-row { + display: flex; padding: 5px 10px; + } + .feed-item-row:hover { background-color: #222; } + .feed-item-row, .feed-item-row * { + cursor: pointer; + } + + .feed-item-row .title-container { + color: var(--color-text-lighter); + + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + } + + .feed-item-row .title-container.unread { + color: var(--color-main-text); + font-weight: bold; + } + + .feed-item-row .intro { + color: var(--color-text-lighter); + font-size: 10pt; + font-weight: normal; + margin-left: 20px; + } + + .feed-item-row .date-container { + padding-left: 4px; + } + + .feed-item-row .button-container { + display: flex; + flex-direction: row; + align-self: start; + } + + .button-container .action-item .button-vue, .button-container .material-design-icon { + width: 30px !important; + min-width: 30px; + min-height: 30px; + height: 30px; + } + .material-design-icon { color: #555555; } @@ -83,11 +249,47 @@ export default { color: var(--color-main-text); } + .material-design-icon.rss-icon:hover { + color: #555555; + } + .material-design-icon.starred { color: rgb(255, 204, 0); } + .material-design-icon.keep-unread { + color: var(--color-main-text); + } + .material-design-icon.starred:hover { color: #555555; } + + .article { + padding: 0 50px 50px 50px; + } + + .article .body { + color: var(--color-main-text); + font-size: 15px; + } + + .article a { + text-decoration: underline; + } + + .article .body a { + color: #3a84e4 + } + + .article .subtitle { + color: var(--color-text-lighter); + font-size: 15px; + padding: 25px 0; + } + + .article .author { + color: var(--color-text-lighter); + font-size: 15px; + } </style> diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 5ef486d85..0cad27654 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -29,7 +29,7 @@ </NcAppNavigationItem> <NcAppNavigationItem :title="t('news', 'Starred')" icon="icon-starred" :to="{ name: ROUTES.STARRED }"> <template #counter> - <NcCounterBubble>35</NcCounterBubble> + <NcCounterBubble>{{ items.starredCount }}</NcCounterBubble> </template> </NcAppNavigationItem> @@ -178,7 +178,7 @@ export default Vue.extend({ } }, computed: { - ...mapState(['feeds', 'folders']), + ...mapState(['feeds', 'folders', 'items']), ...mapState(SideBarState), }, created() { diff --git a/src/components/Starred.vue b/src/components/Starred.vue index fee219f79..60a2ae6bb 100644 --- a/src/components/Starred.vue +++ b/src/components/Starred.vue @@ -2,6 +2,9 @@ <div> <div style="padding-left: 50px; position: absolute; top: 1em; font-weight: 700;"> Starred + <NcCounterBubble style="display: inline-block; vertical-align: sub; margin-left: 10px;"> + {{ items.starredCount }} + </NcCounterBubble> </div> <VirtualScroll :reached-end="items.starredLoaded" style="margin-top: 50px; border-top: 1px solid var(--color-border);"> <template v-if="items.starredItems && items.starredItems.length > 0"> @@ -14,12 +17,16 @@ </template> <script lang="ts"> +import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' + import { mapState } from 'vuex' -import FeedItem from './FeedItem.vue' + import VirtualScroll from './VirtualScroll.vue' +import FeedItem from './FeedItem.vue' export default { components: { + NcCounterBubble, VirtualScroll, FeedItem, }, diff --git a/src/store/item.ts b/src/store/item.ts index d108e34a7..c10360c04 100644 --- a/src/store/item.ts +++ b/src/store/item.ts @@ -13,6 +13,8 @@ export type ItemState = { fetchingItems: boolean; starredLoaded: boolean; + starredCount: number; + allItems: FeedItem[]; starredItems: FeedItem[]; } @@ -21,6 +23,8 @@ const state: ItemState = { fetchingItems: false, starredLoaded: false, + starredCount: 0, + allItems: [], starredItems: [], } @@ -46,6 +50,7 @@ export const actions = { }) commit(FEED_ITEM_MUTATION_TYPES.SET_STARRED, response.data.items) + commit(FEED_ITEM_MUTATION_TYPES.SET_STARRED_COUNT, response.data.starred) if (response.data.items.length < 40) { state.starredLoaded = true @@ -60,6 +65,10 @@ export const mutations = { state.starredItems.push(it) }) }, + [FEED_ITEM_MUTATION_TYPES.SET_STARRED_COUNT](state: ItemState, count: number) { + state.starredCount = count + }, + } export default { diff --git a/src/types/MutationTypes.ts b/src/types/MutationTypes.ts index 9149da059..cb87a1719 100644 --- a/src/types/MutationTypes.ts +++ b/src/types/MutationTypes.ts @@ -10,4 +10,5 @@ export const FOLDER_MUTATION_TYPES = { export const FEED_ITEM_MUTATION_TYPES = { SET_STARRED: 'SET_STARRED', + SET_STARRED_COUNT: 'SET_STARRED_COUNT', } |