Fix some issues and start cleaning up stuff

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
This commit is contained in:
Carl Schwan 2022-08-31 22:15:37 +02:00
parent 47cc783b63
commit cecb507302
No known key found for this signature in database
GPG Key ID: C3AA6B3A5EFA7AC5
4 changed files with 201 additions and 105 deletions

View File

@ -1,22 +1,22 @@
<template>
<Content app-name="news">
<NcContent app-name="news">
<Sidebar />
<AppContent>
<NcAppContent>
<router-view />
</AppContent>
</Content>
</NcAppContent>
</NcContent>
</template>
<script>
import Content from '@nextcloud/vue/dist/Components/Content'
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
import NcContent from '@nextcloud/vue/dist/Components/NcContent.js'
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
import Sidebar from './components/Sidebar.vue'
export default {
components: {
Content,
NcContent,
NcAppContent,
Sidebar,
AppContent,
},
created() {
this.$store.dispatch('loadFolder')

54
src/api.js Normal file
View File

@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
// SPDX-Licence-Identifier: AGPL-3.0-or-later
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
export default {
folder: {
async create(name) {
const { data } = await axios.post(generateUrl('/apps/news/api/v2/folders'), {
name,
})
return data.folders
},
async update(folderId, name) {
await axios.patch(generateUrl('/apps/news/api/v2/folders/{folderId}', {
folderId,
name,
}))
},
async delete(folderId) {
await axios.post(generateUrl('/apps/news/api/v2/folders/{folderId}', {
folderId,
}))
},
async index() {
const { data } = await axios.post(generateUrl('/apps/news/api/v1-3/folders'))
return data.folders
},
async read(folderId, newestItemId = 0) {
const { data } = await axios.post(generateUrl('/apps/news/api/v1-3/folders/{folderId}/read', {
folderId,
}, {
newestItemId,
}))
},
},
feed: {
async get() {
const { data } = await axios.get(generateUrl('/apps/news/feeds'))
return data.feeds
}
async add({ feedUrl, folderId }) {
let url = feedUrl.trim()
if (!url.startsWith('http')) {
url = 'https://' + url
}
const { data } = await axios.post(generateUrl('/apps/news/feeds'), {
folderId,
url,
})
},
},
}

View File

@ -1,107 +1,82 @@
<template>
<NcModal @close="$emit('close')">
<div id="new-feed" news-add-feed="Navigation.feed">
<form ng-submit="Navigation.createFeed(Navigation.feed)"
ng-init="Navigation.feed.autoDiscover=true"
name="feedform">
<fieldset ng-disabled="Navigation.addingFeed" style="padding: 16px">
<input type="text"
:value="feed"
ng-model="Navigation.feed.url"
ng-class="{'ng-invalid':
!Navigation.addingFeed &&
Navigation.feedUrlExists(Navigation.feed.url)
}"
:placeholder="t('news', 'Web address')"
name="address"
pattern="[^\s]+"
required
autofocus>
<NcModal @close="$emit('close')" :title="t('news', 'Add new feed')">
<div class="add-feed">
<h2>{{ t('news', 'Add new feed') }}</h2>
<form ng-submit="Navigation.createFeed(Navigation.feed)" name="feedform">
<NcTextField type="text"
:value.sync="feedUrl"
:label="t('news', 'Web address')"
placeholder="https://..."
:labelVisible="true"
pattern="[^\s]+"
required
autofocus
:error="feedAlreadyExists" />
<p class="error"
ng-show="!Navigation.addingFeed &&
Navigation.feedUrlExists(Navigation.feed.url)">
{{ t("news", "Feed exists already!") }}
</p>
<!-- select a folder -->
<NcCheckboxRadioSwitch :checked.sync="createNewFolder" type="switch">
{{ t("news", "New folder") }}?
</NcCheckboxRadioSwitch>
<!-- select a folder -->
<CheckboxRadioSwitch :checked.sync="createNewFolder" type="switch">
{{ t("news", "New folder") }}?
</CheckboxRadioSwitch>
<NcMultiselect v-if="!createNewFolder"
v-model="folder"
<div v-if="!createNewFolder">
<label for="name">{{ t('news', 'Folder name') }}</label>
<NcMultiselect v-model="folder"
:options="folders"
track-by="id"
label="name" />
</div>
<!-- add a folder -->
<input v-if="createNewFolder"
type="text"
ng-model="Navigation.feed.newFolder"
ng-class="{'ng-invalid':
!Navigation.addingFeed &&
!Navigation.addingFeed &&
Navigation.showNewFolder &&
Navigation.folderNameExists(
Navigation.feed.newFolder
)
}"
:placeholder="t('news', 'Folder name')"
name="folderName"
style="width: 90%"
required>
<!-- add a folder -->
<NcTextField v-if="createNewFolder"
:label="t('news', 'Folder name')"
:labelVisible="true"
:value.sync="folderName"
required />
<p class="error"
ng-show="!Navigation.addingFeed &&
Navigation.folderNameExists(Navigation.feed.newFolder)">
{{ t("news", "Folder exists already!") }}
<!-- basic auth -->
<NcCheckboxRadioSwitch :checked.sync="withBasicAuth" type="switch">
{{ t("news", "Credentials") }}?
</NcCheckboxRadioSwitch>
<fieldset v-if="withBasicAuth" class="add-feed-basicauth">
<p class="warning">
{{
t(
"news",
"HTTP Basic Auth credentials must be stored unencrypted! Everyone with access to the server or database will be able to access them!"
)
}}>
</p>
<NcTextField type="text"
:label="t('news', 'Username')"
:labelVisible="true"
:value="username"
name="user"
autofocus />
<!-- basic auth -->
<CheckboxRadioSwitch :checked.sync="withBasicAuth" type="switch">
{{ t("news", "Credentials") }}?
</CheckboxRadioSwitch>
<div v-if="withBasicAuth" class="add-feed-basicauth">
<p class="warning">
{{
t(
"news",
"HTTP Basic Auth credentials must be stored unencrypted! Everyone with access to the server or database will be able to access them!"
)
}}>
</p>
<input type="text"
ng-model="Navigation.feed.user"
:placeholder="t('news', 'Username')"
name="user"
autofocus>
<input type="password"
ng-model="Navigation.feed.password"
:placeholder="t('news', 'Password')"
name="password"
autocomplete="new-password">
</div>
<NcCheckboxRadioSwitch :checked.sync="autoDiscover" type="switch">
{{ t("news", "Auto discover Feed") }}?
</NcCheckboxRadioSwitch>
<NcButton :wide="true"
type="primary"
ng-disabled="
Navigation.feedUrlExists(Navigation.feed.url) ||
(
Navigation.showNewFolder &&
Navigation.folderNameExists(folder.name)
)"
@click="addFeed()">
{{ t("news", "Subscribe") }}
</NcButton>
<NcTextField type="password"
:label="t('news', 'Password')"
:labelVisible="true"
:value="password"
name="password"
autocomplete="new-password" />
</fieldset>
<NcCheckboxRadioSwitch :checked.sync="autoDiscover" type="switch">
{{ t("news", "Auto discover Feed") }}?
</NcCheckboxRadioSwitch>
<NcButton :wide="true"
type="primary"
ng-disabled="
Navigation.feedUrlExists(Navigation.feed.url) ||
(
Navigation.showNewFolder &&
Navigation.folderNameExists(folder.name)
)"
@click="addFeed()">
{{ t("news", "Subscribe") }}
</NcButton>
</form>
</div>
</NcModal>
@ -114,6 +89,7 @@ import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
export default {
name: 'AddFeed',
@ -122,6 +98,7 @@ export default {
NcCheckboxRadioSwitch,
NcButton,
NcMultiselect,
NcTextField,
},
props: {
feed: '',
@ -129,10 +106,15 @@ export default {
emits: ['close'],
data() {
return {
feedUrl: '',
folderName: '',
password: '',
username: '',
folder: {},
autoDiscover: true,
createNewFolder: false,
withBasicAuth: false,
feedAlreadyExists: false,
}
},
computed: {
@ -160,7 +142,15 @@ export default {
}
</script>
<style scoped>
<style scoped lang="scss">
.add-feed {
padding: 1rem;
form {
display: flex;
flex-direction: column;
gap: 1rem;
}
}
input {
width: 100%
}

View File

@ -22,9 +22,12 @@
<img :src="entry.image">
</div>
</div>
<Button @click="subscribe(entry.feed)">
{{ t("news", "Subscribe to") }} {{ entry.title }}
</Button>
<NcButton @click="subscribe(entry.feed)"
type="primary"
class="grid-item__button"
:wide="true">
{{ t("news", "Subscribe to {title}", {title: entry.title}) }}
</NcButton>
</div>
</div>
</div>
@ -76,3 +79,52 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.grid-container {
padding: 1rem;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
/* This is better for small screens, once min() is better supported */
/* grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); */
gap: 1rem;
.grid-item {
border: 2px solid var(--color-border);
border-radius: var(--border-radius-large);
padding: 1rem;
display: flex;
flex-direction: column;
&__button {
margin-top: auto;
}
}
.grid-item .explore-title {
background-repeat: no-repeat;
background-position: 0 center;
background-size: 24px;
padding-left: 32px;
}
.grid-item .explore-title a {
word-wrap: break-word;
}
.grid-item .explore-title a:hover, #explore .grid-item .explore-title a:focus {
text-decoration: underline;
}
.grid-item .explore-logo {
text-align: center;
margin-top: 25px;
}
.grid-item .explore-logo img {
width: 100%;
}
.grid-item .explore-subscribe {
margin-top: 16px;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
</style>