forked from AkkomaGang/akkoma-fe
make reusable Exporter component
This commit is contained in:
parent
0ab2f9dfa5
commit
08eaf9bd33
5 changed files with 88 additions and 39 deletions
47
src/components/exporter/exporter.js
Normal file
47
src/components/exporter/exporter.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
const Exporter = {
|
||||||
|
props: {
|
||||||
|
getContent: {
|
||||||
|
type: Function,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
filename: {
|
||||||
|
type: String,
|
||||||
|
default: 'export.csv'
|
||||||
|
},
|
||||||
|
exportButtonLabel: {
|
||||||
|
type: String,
|
||||||
|
default () {
|
||||||
|
return this.$t('exporter.export')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
processingMessage: {
|
||||||
|
type: String,
|
||||||
|
default () {
|
||||||
|
return this.$t('exporter.processing')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
processing: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
process () {
|
||||||
|
this.processing = true
|
||||||
|
this.getContent()
|
||||||
|
.then((content) => {
|
||||||
|
const fileToDownload = document.createElement('a')
|
||||||
|
fileToDownload.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(content))
|
||||||
|
fileToDownload.setAttribute('download', this.filename)
|
||||||
|
fileToDownload.style.display = 'none'
|
||||||
|
document.body.appendChild(fileToDownload)
|
||||||
|
fileToDownload.click()
|
||||||
|
document.body.removeChild(fileToDownload)
|
||||||
|
setTimeout(() => { this.processing = false }, 2000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Exporter
|
20
src/components/exporter/exporter.vue
Normal file
20
src/components/exporter/exporter.vue
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<template>
|
||||||
|
<div class="exporter">
|
||||||
|
<div v-if="processing">
|
||||||
|
<i class="icon-spin4 animate-spin exporter-processing"></i>
|
||||||
|
<span>{{processingMessage}}</span>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-default" @click="process" v-else>{{exportButtonLabel}}</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./exporter.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.exporter {
|
||||||
|
&-processing {
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0.25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -14,6 +14,7 @@ import ProgressButton from '../progress_button/progress_button.vue'
|
||||||
import EmojiInput from '../emoji-input/emoji-input.vue'
|
import EmojiInput from '../emoji-input/emoji-input.vue'
|
||||||
import Autosuggest from '../autosuggest/autosuggest.vue'
|
import Autosuggest from '../autosuggest/autosuggest.vue'
|
||||||
import Importer from '../importer/importer.vue'
|
import Importer from '../importer/importer.vue'
|
||||||
|
import Exporter from '../exporter/exporter.vue'
|
||||||
import withSubscription from '../../hocs/with_subscription/with_subscription'
|
import withSubscription from '../../hocs/with_subscription/with_subscription'
|
||||||
import userSearchApi from '../../services/new_api/user_search.js'
|
import userSearchApi from '../../services/new_api/user_search.js'
|
||||||
|
|
||||||
|
@ -41,7 +42,6 @@ const UserSettings = {
|
||||||
hideFollowers: this.$store.state.users.currentUser.hide_followers,
|
hideFollowers: this.$store.state.users.currentUser.hide_followers,
|
||||||
showRole: this.$store.state.users.currentUser.show_role,
|
showRole: this.$store.state.users.currentUser.show_role,
|
||||||
role: this.$store.state.users.currentUser.role,
|
role: this.$store.state.users.currentUser.role,
|
||||||
enableFollowsExport: true,
|
|
||||||
pickAvatarBtnVisible: true,
|
pickAvatarBtnVisible: true,
|
||||||
bannerUploading: false,
|
bannerUploading: false,
|
||||||
backgroundUploading: false,
|
backgroundUploading: false,
|
||||||
|
@ -73,7 +73,8 @@ const UserSettings = {
|
||||||
BlockCard,
|
BlockCard,
|
||||||
MuteCard,
|
MuteCard,
|
||||||
ProgressButton,
|
ProgressButton,
|
||||||
Importer
|
Importer,
|
||||||
|
Exporter
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
user () {
|
user () {
|
||||||
|
@ -250,38 +251,19 @@ const UserSettings = {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/* This function takes an Array of Users
|
getFollowsContent () {
|
||||||
* and outputs a file with all the addresses for the user to download
|
return this.$store.state.api.backendInteractor.exportFriends({ id: this.$store.state.users.currentUser.id })
|
||||||
*/
|
|
||||||
exportPeople (users, filename) {
|
|
||||||
// Get all the friends addresses
|
|
||||||
var UserAddresses = users.map(function (user) {
|
|
||||||
// check is it's a local user
|
|
||||||
if (user && user.is_local) {
|
|
||||||
// append the instance address
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
user.screen_name += '@' + location.hostname
|
|
||||||
}
|
|
||||||
return user.screen_name
|
|
||||||
}).join('\n')
|
|
||||||
// Make the user download the file
|
|
||||||
var fileToDownload = document.createElement('a')
|
|
||||||
fileToDownload.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(UserAddresses))
|
|
||||||
fileToDownload.setAttribute('download', filename)
|
|
||||||
fileToDownload.style.display = 'none'
|
|
||||||
document.body.appendChild(fileToDownload)
|
|
||||||
fileToDownload.click()
|
|
||||||
document.body.removeChild(fileToDownload)
|
|
||||||
},
|
|
||||||
exportFollows () {
|
|
||||||
this.enableFollowsExport = false
|
|
||||||
this.$store.state.api.backendInteractor
|
|
||||||
.exportFriends({
|
|
||||||
id: this.$store.state.users.currentUser.id
|
|
||||||
})
|
|
||||||
.then((friendList) => {
|
.then((friendList) => {
|
||||||
this.exportPeople(friendList, 'friends.csv')
|
// Get all the friends addresses
|
||||||
setTimeout(() => { this.enableFollowsExport = true }, 2000)
|
return friendList.map((user) => {
|
||||||
|
// check is it's a local user
|
||||||
|
if (user && user.is_local) {
|
||||||
|
// append the instance address
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
return user.screen_name + '@' + location.hostname
|
||||||
|
}
|
||||||
|
return user.screen_name
|
||||||
|
}).join('\n')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
confirmDelete () {
|
confirmDelete () {
|
||||||
|
|
|
@ -173,12 +173,9 @@
|
||||||
<p>{{$t('settings.import_followers_from_a_csv_file')}}</p>
|
<p>{{$t('settings.import_followers_from_a_csv_file')}}</p>
|
||||||
<Importer :submitHandler="importFollows" :successMessage="$t('settings.follows_imported')" :errorMessage="$t('settings.follow_import_error')" />
|
<Importer :submitHandler="importFollows" :successMessage="$t('settings.follows_imported')" :errorMessage="$t('settings.follow_import_error')" />
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item" v-if="enableFollowsExport">
|
<div class="setting-item">
|
||||||
<h2>{{$t('settings.follow_export')}}</h2>
|
<h2>{{$t('settings.follow_export')}}</h2>
|
||||||
<button class="btn btn-default" @click="exportFollows">{{$t('settings.follow_export_button')}}</button>
|
<Exporter :getContent="getFollowsContent" filename="friends.csv" :exportButtonLabel="$t('settings.follow_export_button')" />
|
||||||
</div>
|
|
||||||
<div class="setting-item" v-else>
|
|
||||||
<h2>{{$t('settings.follow_export_processing')}}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{$t('settings.block_import')}}</h2>
|
<h2>{{$t('settings.block_import')}}</h2>
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
"chat": {
|
"chat": {
|
||||||
"title": "Chat"
|
"title": "Chat"
|
||||||
},
|
},
|
||||||
|
"exporter": {
|
||||||
|
"export": "Export",
|
||||||
|
"processing": "Processing, you'll soon be asked to download your file"
|
||||||
|
},
|
||||||
"features_panel": {
|
"features_panel": {
|
||||||
"chat": "Chat",
|
"chat": "Chat",
|
||||||
"gopher": "Gopher",
|
"gopher": "Gopher",
|
||||||
|
@ -161,7 +165,6 @@
|
||||||
"filtering_explanation": "All statuses containing these words will be muted, one per line",
|
"filtering_explanation": "All statuses containing these words will be muted, one per line",
|
||||||
"follow_export": "Follow export",
|
"follow_export": "Follow export",
|
||||||
"follow_export_button": "Export your follows to a csv file",
|
"follow_export_button": "Export your follows to a csv file",
|
||||||
"follow_export_processing": "Processing, you'll soon be asked to download your file",
|
|
||||||
"follow_import": "Follow import",
|
"follow_import": "Follow import",
|
||||||
"follow_import_error": "Error importing followers",
|
"follow_import_error": "Error importing followers",
|
||||||
"follows_imported": "Follows imported! Processing them will take a while.",
|
"follows_imported": "Follows imported! Processing them will take a while.",
|
||||||
|
|
Loading…
Reference in a new issue