summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDevlin Junker <devlin.junker@gmail.com>2023-08-15 13:11:22 -0700
committerBenjamin Brahmer <info@b-brahmer.de>2023-08-22 08:34:39 +0200
commitd14dbe3fb10aa0280063b66226347a0c12fb219c (patch)
tree9d585638c33faefec3285fb1d9ce1ccc9ca39e45 /src
parent41213ad4869ee22d15bf148509b0ddc7a538f1cb (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.vue232
-rw-r--r--src/components/Sidebar.vue4
-rw-r--r--src/components/Starred.vue9
-rw-r--r--src/store/item.ts9
-rw-r--r--src/types/MutationTypes.ts1
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',
}