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

Vue improvements #2401

Merged
merged 25 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
95e8b7a
maintain aspect ratio of images
powerpaul17 Oct 25, 2023
3a695bc
move NcAppContent into route components & use list slot
powerpaul17 Oct 25, 2023
9568c78
show feed item in content detail
powerpaul17 Oct 25, 2023
5906910
set max width for article view and center it
powerpaul17 Oct 25, 2023
be1ed07
use template component for list/content views
powerpaul17 Oct 26, 2023
ec75eb9
wrap list and details in the corresponding nextcloud components
powerpaul17 Oct 28, 2023
8e49a53
show/hide details according to item selection
powerpaul17 Oct 28, 2023
b87386a
fix article scrolling
powerpaul17 Oct 28, 2023
ebf0bce
use favicon as link to feed item
powerpaul17 Oct 28, 2023
2d9f100
improve feed item list item
powerpaul17 Oct 28, 2023
7408b7d
add changelog entry for frontend improvements
powerpaul17 Oct 28, 2023
3bb457b
linting
powerpaul17 Oct 28, 2023
35587e4
improve changelog entries
powerpaul17 Oct 28, 2023
8280367
add missing nc app content component to explore page
powerpaul17 Oct 29, 2023
921b80f
use type import for PropType
powerpaul17 Oct 29, 2023
8560233
do not import unused component
powerpaul17 Oct 29, 2023
88bbf95
reformat emit definition to satisfy linter
powerpaul17 Oct 29, 2023
e609f8d
use @vue/vue2-jest package instead of vue-jest
powerpaul17 Oct 29, 2023
bfbee86
adapt tests to use new content template component
powerpaul17 Oct 29, 2023
45bc6b2
add note about composition api
powerpaul17 Oct 30, 2023
f4dd375
pass empty array instead of undefined for unread items
powerpaul17 Nov 1, 2023
863e9ac
show empty content component when no article is selected
powerpaul17 Nov 1, 2023
5f38364
remove unnecessary height of app content details component
powerpaul17 Nov 1, 2023
511ac89
move css style into class
powerpaul17 Nov 1, 2023
5410721
remove (now) unsuitable test for folder name/unread count in feed lis…
powerpaul17 Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The format is mostly based on [Keep a Changelog](https://keepachangelog.com/en/1
# Unreleased
## [25.x.x]
### Changed
- Improvements to Vue frontend
powerpaul17 marked this conversation as resolved.
Show resolved Hide resolved

### Fixed

Expand Down
10 changes: 1 addition & 9 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
<div id="news-app">
<div id="content-display" :class="{ playing: playingItem }">
<Sidebar />
<NcAppContent>
<RouterView />
</NcAppContent>
<RouterView />
</div>
<div v-if="playingItem" class="podcast">
<audio controls
Expand All @@ -50,15 +48,13 @@
import Vue from 'vue'
import { mapState } from 'vuex'
import NcContent from '@nextcloud/vue/dist/Components/NcContent.js'
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
import Sidebar from './components/Sidebar.vue'
import { ACTIONS, MUTATIONS } from './store'

export default Vue.extend({
components: {
NcContent,
Sidebar,
NcAppContent,
},
computed: {
playingItem() {
Expand Down Expand Up @@ -120,10 +116,6 @@ export default Vue.extend({
font-size: small;
}

.route-container {
height: 100%;
}

#content-display {
display: flex;
flex-direction: row;
Expand Down
92 changes: 92 additions & 0 deletions src/components/ContentTemplate.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<template>
<NcAppContent :show-details="showDetails"
@update:showDetails="unselectItem()">
<template #list>
<NcAppContentList>
<div class="header">
<slot name="header" />
</div>

<FeedItemDisplayList :items="items"
:fetch-key="fetchKey"
:config="config"
@load-more="emit('load-more')" />
</NcAppContentList>
</template>

<NcAppContentDetails class="content-details-container">
<FeedItemDisplay v-if="selectedFeedItem" :item="selectedFeedItem" />
</NcAppContentDetails>
</NcAppContent>
</template>

<script setup lang="ts">

import { PropType, computed, ref, watch } from 'vue'

Check failure on line 25 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint node

PropType not found in 'vue'

Check failure on line 25 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint

PropType not found in 'vue'
powerpaul17 marked this conversation as resolved.
Show resolved Hide resolved

import itemStore from '../store/item'

import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent'
import NcAppContentList from '@nextcloud/vue/dist/Components/NcAppContentList'
import NcAppContentDetails from '@nextcloud/vue/dist/Components/NcAppContentDetails'

import { FeedItem } from '../types/FeedItem'

import FeedItemDisplayList from './feed-display/FeedItemDisplayList.vue'
import FeedItemDisplay from './feed-display/FeedItemDisplay.vue'

powerpaul17 marked this conversation as resolved.
Show resolved Hide resolved
defineProps({
powerpaul17 marked this conversation as resolved.
Show resolved Hide resolved
items: {
type: Array as PropType<Array<FeedItem>>,
required: true,
},
fetchKey: {
type: String,
required: true,
},
config: {

Check warning on line 47 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint node

Prop 'config' requires default value to be set

Check warning on line 47 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint

Prop 'config' requires default value to be set
type: Object,
},
})

const emit = defineEmits<{

Check failure on line 52 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint node

Unexpected whitespace between function name and paren

Check failure on line 52 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint

Unexpected whitespace between function name and paren
(event: 'load-more'): void
}>()

const showDetails = ref(false)

const selectedFeedItem = computed(() => {
return itemStore.getters.selected(itemStore.state)
powerpaul17 marked this conversation as resolved.
Show resolved Hide resolved
})

watch(selectedFeedItem, (newSelectedFeedItem) => {
if (newSelectedFeedItem) {
showDetails.value = true
} else {
showDetails.value = false
}
})

function unselectItem() {

Check warning on line 70 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint node

Missing JSDoc comment

Check warning on line 70 in src/components/ContentTemplate.vue

View workflow job for this annotation

GitHub Actions / eslint

Missing JSDoc comment
itemStore.mutations.SET_SELECTED_ITEM(
itemStore.state,
{ id: undefined },
)
}

</script>

<style scoped>

.header {
padding-left: 50px;
position: absolute;
top: 1em;
font-weight: 700;
}

.content-details-container {
height: 100%
}

</style>
4 changes: 4 additions & 0 deletions src/components/feed-display/FeedItemDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@
<img v-else :src="item.mediaThumbnail" alt="">
</div>

<div v-if="item.mediaDescription" class="enclosure description" v-html="item.mediaDescription" />

Check warning on line 88 in src/components/feed-display/FeedItemDisplay.vue

View workflow job for this annotation

GitHub Actions / eslint node

'v-html' directive can lead to XSS attack

Check warning on line 88 in src/components/feed-display/FeedItemDisplay.vue

View workflow job for this annotation

GitHub Actions / eslint

'v-html' directive can lead to XSS attack

<div class="body" :dir="item.rtl && 'rtl'" v-html="item.body" />

Check warning on line 90 in src/components/feed-display/FeedItemDisplay.vue

View workflow job for this annotation

GitHub Actions / eslint node

'v-html' directive can lead to XSS attack

Check warning on line 90 in src/components/feed-display/FeedItemDisplay.vue

View workflow job for this annotation

GitHub Actions / eslint

'v-html' directive can lead to XSS attack
</div>
</div>
</template>
Expand Down Expand Up @@ -208,6 +208,9 @@
padding: 0 50px 50px 50px;
overflow-y: scroll;
height: 100%;
max-width: 1024px;
margin-left: auto;
margin-right: auto;
}

.article video {
Expand Down Expand Up @@ -267,6 +270,7 @@

.article img {
width: 100%;
height: auto;
}

.article h1 {
Expand Down
25 changes: 0 additions & 25 deletions src/components/feed-display/FeedItemDisplayList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@
</template>
</template>
</VirtualScroll>

<div v-if="selected !== undefined" class="feed-item-container">
<FeedItemDisplay :item="selected" />
powerpaul17 marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
</div>
</template>
Expand Down Expand Up @@ -71,7 +67,7 @@
components: {
VirtualScroll,
FeedItemRow,
FeedItemDisplay,

Check failure on line 70 in src/components/feed-display/FeedItemDisplayList.vue

View workflow job for this annotation

GitHub Actions / eslint node

The "FeedItemDisplay" component has been registered but not used

Check failure on line 70 in src/components/feed-display/FeedItemDisplayList.vue

View workflow job for this annotation

GitHub Actions / eslint

The "FeedItemDisplay" component has been registered but not used
FilterIcon,
StarIcon,
StarCheckIcon,
Expand Down Expand Up @@ -115,9 +111,6 @@
}
},
computed: {
selected(): FeedItem | undefined {
return this.$store.getters.selected
},
reachedEnd(): boolean {
return this.mounted && this.$store.state.items.allItemsLoaded[this.fetchKey] === true
},
Expand Down Expand Up @@ -206,30 +199,12 @@
.feed-item-display-container {
flex-direction: column;
}

.feed-item-container {
flex: 1 1 1000px;
max-height: calc(100vh - 200px)
}
}

@media only screen and (min-width: 768px) {
.feed-item-display-container {
flex-direction: row;
}

.feed-item-container {
width: 50%;
max-height: unset;
}
}

.feed-item-container {
overflow-y: hidden;
-webkit-box-shadow: 1px -1px 5px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 1px -1px 5px 0px rgba(0,0,0,0.75);
box-shadow: 1px -1px 5px 0px rgba(0,0,0,0.75);
border-top: 1px solid var(--color-border);
}

.header {
Expand Down
62 changes: 42 additions & 20 deletions src/components/feed-display/FeedItemRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,31 @@
:href="item.url"
:title="t('news', 'Open website')"
@click="markRead(item); $event.stopPropagation();">
<EarthIcon />
<span v-if="getFeed(item.feedId).faviconLink"
class="favicon"
:style="{ 'backgroundImage': 'url(' + getFeed(item.feedId).faviconLink + ')' }" />
<RssIcon v-else />
</a>
<RssIcon v-if="!getFeed(item.feedId).faviconLink" />
<span v-if="getFeed(item.feedId).faviconLink" style="width: 24px; background-size: contain;" :style="{ 'backgroundImage': 'url(' + getFeed(item.feedId).faviconLink + ')' }" />
</div>
<div class="title-container" :class="{ 'unread': item.unread }">
<span style="white-space: nowrap" :dir="item.rtl && 'rtl'">
{{ item.title }}

<div class="main-container">
<div class="title-container" :class="{ 'unread': item.unread }">
<span style="white-space: nowrap" :dir="item.rtl && 'rtl'">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this style be moved to a css rule?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just moved, I did not change/add it.. but I can move it into a class if you like.. 😉

{{ item.title }}
</span>
</div>

<div class="intro-container">
<span class="intro" v-html="item.intro" />

Check warning on line 26 in src/components/feed-display/FeedItemRow.vue

View workflow job for this annotation

GitHub Actions / eslint node

'v-html' directive can lead to XSS attack

Check warning on line 26 in src/components/feed-display/FeedItemRow.vue

View workflow job for this annotation

GitHub Actions / eslint

'v-html' directive can lead to XSS attack
</span>
</div>
<div class="date-container">
<time class="date" :title="formatDate(item.pubDate*1000, 'yyyy-MM-dd HH:mm:ss')" :datetime="formatDatetime(item.pubDate*1000, 'yyyy-MM-ddTHH:mm:ssZ')">
{{ getRelativeTimestamp(item.pubDate*1000) }}
</time>
</div>

<div class="date-container">
<time class="date" :title="formatDate(item.pubDate*1000, 'yyyy-MM-dd HH:mm:ss')" :datetime="formatDatetime(item.pubDate*1000, 'yyyy-MM-ddTHH:mm:ssZ')">
{{ getRelativeTimestamp(item.pubDate*1000) }}
</time>
</div>
</div>

<div class="button-container" @click="$event.stopPropagation()">
<StarIcon :class="{'starred': item.starred }" @click="toggleStarred(item)" />
<EyeIcon v-if="item.unread && !keepUnread" @click="toggleKeepUnread(item)" />
Expand All @@ -45,7 +54,6 @@
import Vue from 'vue'
import { mapState } from 'vuex'

import EarthIcon from 'vue-material-design-icons/Earth.vue'
import StarIcon from 'vue-material-design-icons/Star.vue'
import EyeIcon from 'vue-material-design-icons/Eye.vue'
import EyeCheckIcon from 'vue-material-design-icons/EyeCheck.vue'
Expand All @@ -65,7 +73,6 @@
export default Vue.extend({
name: 'FeedItemRow',
components: {
EarthIcon,
StarIcon,
EyeIcon,
EyeCheckIcon,
Expand Down Expand Up @@ -153,7 +160,7 @@

<style>
.feed-item-row {
display: flex; padding: 5px 10px;
display: flex; padding: 10px 10px;
}

.feed-item-row:hover {
Expand All @@ -165,10 +172,21 @@
}

.feed-item-row .link-container {
padding-right: 5px;
padding-right: 12px;
display: flex;
flex-direction: row;
align-self: start;
align-self: center;
}

.favicon {
height: 24px;
width: 24px;
display: inline-block;
background-size: contain;
}

.feed-item-row .main-container {
min-width: 0;
}

.feed-item-row .title-container {
Expand All @@ -184,11 +202,16 @@
font-weight: bold;
}

.feed-item-row .intro-container {
line-height: initial;
height: 32pt;
overflow: hidden;
}

.feed-item-row .intro {
color: var(--color-text-lighter);
font-size: 10pt;
font-weight: normal;
margin-left: 20px;
}

@media only screen and (min-width: 320px) {
Expand All @@ -205,14 +228,13 @@

.feed-item-row .date-container {
color: var(--color-text-lighter);
padding-left: 4px;
white-space: nowrap;
}

.feed-item-row .button-container {
display: flex;
flex-direction: row;
align-self: start;
align-self: center;
}

.feed-item-row .button-container .button-vue, .feed-item-row .button-container .button-vue .button-vue__wrapper, .feed-item-row .button-container .material-design-icon {
Expand Down
29 changes: 8 additions & 21 deletions src/components/routes/All.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
<template>
<div class="route-container">
<div class="header">
<ContentTemplate :items="allItems"
:fetch-key="'all'"
@load-more="fetchMore()">
<template #header>
{{ t('news', 'All Articles') }}
</div>

<FeedItemDisplayList :items="allItems"
:fetch-key="'all'"
@load-more="fetchMore()" />
</div>
</template>
</ContentTemplate>
</template>

<script lang="ts">
import Vue from 'vue'
import { mapState } from 'vuex'

import FeedItemDisplayList from '../feed-display/FeedItemDisplayList.vue'
import ContentTemplate from '../ContentTemplate.vue'

import { FeedItem } from '../../types/FeedItem'
import { ACTIONS, MUTATIONS } from '../../store'

export default Vue.extend({
components: {
FeedItemDisplayList,
ContentTemplate,
},
computed: {
...mapState(['items']),
Expand All @@ -44,17 +42,6 @@ export default Vue.extend({
</script>

<style scoped>
.route-container {
height: 100%;
}

.header {
padding-left: 50px;
position: absolute;
top: 1em;
font-weight: 700;
}

.counter-bubble {
display: inline-block;
vertical-align: sub;
Expand Down
Loading
Loading