Skip to content

Commit

Permalink
add import/export opml to user settings
Browse files Browse the repository at this point in the history
Signed-off-by: Wolfgang <[email protected]>
  • Loading branch information
wofferl committed Nov 18, 2024
1 parent 3ac7db1 commit f530595
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ You can also check [on GitHub](https://github.com/nextcloud/news/releases), the
- If title of feed is empty during creation set hostname of feed as title (#2872)
- Add command to import OPML file
- Add API to import OPML file or request body
- add import/export `opml` to user settings (#2541)

### Fixed
- Feed without Title returned by DB causes exception (#2872)
Expand Down
90 changes: 90 additions & 0 deletions src/components/Sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,26 @@
{{ t('news', 'Disable automatic refresh') }}
</label>
</div>
<h1>{{ t('news', 'Abonnements (OPML)') }}</h1>
<div class="button-container">
<NcButton aria-label="UploadOpml"
@click="$refs.fileSelect.click()">
<template #icon>
<UploadIcon :size="20" />
</template>
</NcButton>
<input ref="fileSelect"
type="file"
class="hidden"
accept=".opml"
@change="importOpml">
<NcButton aria-label="DownloadOpml"
@click="exportOpml">
<template #icon>
<DownloadIcon :size="20" />
</template>
</NcButton>
</div>
</div>
</NcAppNavigationSettings>
</template>
Expand Down Expand Up @@ -215,6 +235,8 @@ import EarthIcon from 'vue-material-design-icons/Earth.vue'
import FolderPlusIcon from 'vue-material-design-icons/FolderPlus.vue'
import FolderAlertIcon from 'vue-material-design-icons/FolderAlert.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import UploadIcon from 'vue-material-design-icons/Upload.vue'
import DownloadIcon from 'vue-material-design-icons/Download.vue'
import { ROUTES } from '../routes'
import { ACTIONS } from '../store'
Expand Down Expand Up @@ -244,6 +266,8 @@ export default Vue.extend({
FolderAlertIcon,
FolderPlusIcon,
PlusIcon,
UploadIcon,
DownloadIcon,
SidebarFeedLinkActions,
HelpModal,
},
Expand All @@ -253,6 +277,8 @@ export default Vue.extend({
ROUTES,
showHelp: false,
polling: null,
uploadStatus: null,
selectedFile: null,
}
},
computed: {
Expand Down Expand Up @@ -403,6 +429,59 @@ export default Vue.extend({
})
}
},
async importOpml(event) {
const file = event.target.files[0]
if (file && file.type === 'text/x-opml+xml') {
this.selectedFile = file
} else {
showError(t('news', 'Please select a valid OPML file'))
return
}
const formData = new FormData()
formData.append('file', this.selectedFile)
try {
const response = await fetch('import/opml', {
method: 'POST',
body: formData,
})
if (response.ok) {
showSuccess(t('news', 'File successfully uploaded'))
} else {
showError(t('news', 'Error uploading the opml file'))
}
} catch (e) {
this.handleResponse({
errorMessage: t('news', 'Error connecting to the server'),
error: e,
})
}
// refresh feeds and folders after import
this.$store.dispatch(ACTIONS.FETCH_FOLDERS)
this.$store.dispatch(ACTIONS.FETCH_FEEDS)
},
async exportOpml() {
try {
const response = await fetch('export/opml')
if (response.ok) {
const formattedDate = new Date().toISOString().split('T')[0]
const blob = await response.blob()
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = 'subscriptions-' + formattedDate + '.opml'
link.click()
} else {
showError(t('news', 'Error retrieving the opml file'))
}
} catch (e) {
this.handleResponse({
errorMessage: t('news', 'Error connecting to the server'),
error: e,
})
}
},
handleResponse({ status, errorMessage, error }) {
if (status !== 'ok') {
showError(errorMessage)
Expand Down Expand Up @@ -543,3 +622,14 @@ export default Vue.extend({
})
</script>

<style scoped>
.button-container {
display: flex;
width: 100%;
}
.button-container button {
flex: 1;
}
</style>

0 comments on commit f530595

Please sign in to comment.