From 562120ae48945d87a24f2248f9b16185b49159d0 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Fri, 29 Mar 2019 21:58:20 -0400
Subject: [PATCH 01/11] =?UTF-8?q?split=20out=20follow=E2=80=99s=20importer?=
=?UTF-8?q?=20as=20a=20separate=20component?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/importer/importer.js | 36 +++++++++++++++++++
src/components/importer/importer.vue | 19 ++++++++++
src/components/user_settings/user_settings.js | 31 ++--------------
.../user_settings/user_settings.vue | 14 +-------
4 files changed, 59 insertions(+), 41 deletions(-)
create mode 100644 src/components/importer/importer.js
create mode 100644 src/components/importer/importer.vue
diff --git a/src/components/importer/importer.js b/src/components/importer/importer.js
new file mode 100644
index 00000000..8d6c8b3f
--- /dev/null
+++ b/src/components/importer/importer.js
@@ -0,0 +1,36 @@
+const Importer = {
+ data () {
+ return {
+ file: null,
+ error: false,
+ success: false,
+ uploading: false
+ }
+ },
+ methods: {
+ change () {
+ this.file = this.$refs.input.files[0]
+ },
+ submit () {
+ this.uploading = true
+ // eslint-disable-next-line no-undef
+ const formData = new FormData()
+ formData.append('list', this.file)
+ this.$store.state.api.backendInteractor.followImport({params: formData})
+ .then((status) => {
+ if (status) {
+ this.success = true
+ } else {
+ this.error = true
+ }
+ this.uploading = false
+ })
+ },
+ dismiss () {
+ this.success = false
+ this.error = false
+ }
+ }
+}
+
+export default Importer
diff --git a/src/components/importer/importer.vue b/src/components/importer/importer.vue
new file mode 100644
index 00000000..0fd83b7c
--- /dev/null
+++ b/src/components/importer/importer.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
{{$t('settings.follows_imported')}}
+
+
+
+
{{$t('settings.follow_import_error')}}
+
+
+
+
+
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index e88ee612..a213650b 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -13,6 +13,7 @@ import SelectableList from '../selectable_list/selectable_list.vue'
import ProgressButton from '../progress_button/progress_button.vue'
import EmojiInput from '../emoji-input/emoji-input.vue'
import Autosuggest from '../autosuggest/autosuggest.vue'
+import Importer from '../importer/importer.vue'
import withSubscription from '../../hocs/with_subscription/with_subscription'
import userSearchApi from '../../services/new_api/user_search.js'
@@ -40,14 +41,10 @@ const UserSettings = {
hideFollowers: this.$store.state.users.currentUser.hide_followers,
showRole: this.$store.state.users.currentUser.show_role,
role: this.$store.state.users.currentUser.role,
- followList: null,
- followImportError: false,
- followsImported: false,
enableFollowsExport: true,
pickAvatarBtnVisible: true,
bannerUploading: false,
backgroundUploading: false,
- followListUploading: false,
bannerPreview: null,
backgroundPreview: null,
bannerUploadError: null,
@@ -75,7 +72,8 @@ const UserSettings = {
Autosuggest,
BlockCard,
MuteCard,
- ProgressButton
+ ProgressButton,
+ Importer
},
computed: {
user () {
@@ -236,19 +234,6 @@ const UserSettings = {
this.backgroundUploading = false
})
},
- importFollows () {
- this.followListUploading = true
- const followList = this.followList
- this.$store.state.api.backendInteractor.followImport({params: followList})
- .then((status) => {
- if (status) {
- this.followsImported = true
- } else {
- this.followImportError = true
- }
- this.followListUploading = false
- })
- },
/* This function takes an Array of Users
* and outputs a file with all the addresses for the user to download
*/
@@ -283,16 +268,6 @@ const UserSettings = {
setTimeout(() => { this.enableFollowsExport = true }, 2000)
})
},
- followListChange () {
- // eslint-disable-next-line no-undef
- let formData = new FormData()
- formData.append('list', this.$refs.followlist.files[0])
- this.followList = formData
- },
- dismissImported () {
- this.followsImported = false
- this.followImportError = false
- },
confirmDelete () {
this.deletingAccount = true
},
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index d68e68fa..fb91e269 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -171,19 +171,7 @@
{{$t('settings.follow_import')}}
{{$t('settings.import_followers_from_a_csv_file')}}
-
-
-
-
-
-
{{$t('settings.follows_imported')}}
-
-
-
-
{{$t('settings.follow_import_error')}}
-
+
{{$t('settings.follow_export')}}
From 903bce40c3b013ed2f2347c254ea184293b45b22 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Fri, 29 Mar 2019 23:39:24 -0400
Subject: [PATCH 02/11] move formData generating logic to api.service
---
src/components/importer/importer.js | 5 +----
src/services/api/api.service.js | 6 ++++--
.../backend_interactor_service.js | 2 +-
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/src/components/importer/importer.js b/src/components/importer/importer.js
index 8d6c8b3f..44d02c93 100644
--- a/src/components/importer/importer.js
+++ b/src/components/importer/importer.js
@@ -13,10 +13,7 @@ const Importer = {
},
submit () {
this.uploading = true
- // eslint-disable-next-line no-undef
- const formData = new FormData()
- formData.append('list', this.file)
- this.$store.state.api.backendInteractor.followImport({params: formData})
+ this.$store.state.api.backendInteractor.followImport(this.file)
.then((status) => {
if (status) {
this.success = true
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 6b255e9f..3f6ffccc 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -634,9 +634,11 @@ const uploadMedia = ({formData, credentials}) => {
.then((data) => parseAttachment(data))
}
-const followImport = ({params, credentials}) => {
+const followImport = ({file, credentials}) => {
+ const formData = new FormData()
+ formData.append('list', file)
return fetch(FOLLOW_IMPORT_URL, {
- body: params,
+ body: formData,
method: 'POST',
headers: authHeaders(credentials)
})
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 75bba92b..2438c603 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -107,7 +107,7 @@ const backendInteractorService = (credentials) => {
const updateProfile = ({params}) => apiService.updateProfile({credentials, params})
const externalProfile = (profileUrl) => apiService.externalProfile({profileUrl, credentials})
- const followImport = ({params}) => apiService.followImport({params, credentials})
+ const followImport = (file) => apiService.followImport({file, credentials})
const deleteAccount = ({password}) => apiService.deleteAccount({credentials, password})
const changePassword = ({password, newPassword, newPasswordConfirmation}) => apiService.changePassword({credentials, password, newPassword, newPasswordConfirmation})
From 18bb209acefcdc332cba6708d9a0e163d0d04e90 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Fri, 29 Mar 2019 23:55:49 -0400
Subject: [PATCH 03/11] add uploading icon css
---
src/components/importer/importer.vue | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/components/importer/importer.vue b/src/components/importer/importer.vue
index 0fd83b7c..d2447e1a 100644
--- a/src/components/importer/importer.vue
+++ b/src/components/importer/importer.vue
@@ -17,3 +17,12 @@
+
+
From 6d0e98a1c2c81c587b89736dbd2ac43a8c540d54 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Sat, 30 Mar 2019 05:10:57 -0400
Subject: [PATCH 04/11] make Importer component reusable
---
src/components/importer/importer.js | 42 ++++++++++++++-----
src/components/importer/importer.vue | 10 ++---
src/components/user_settings/user_settings.js | 8 ++++
.../user_settings/user_settings.vue | 2 +-
src/i18n/en.json | 5 +++
5 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/src/components/importer/importer.js b/src/components/importer/importer.js
index 44d02c93..c5f9e4d2 100644
--- a/src/components/importer/importer.js
+++ b/src/components/importer/importer.js
@@ -1,10 +1,34 @@
const Importer = {
+ props: {
+ submitHandler: {
+ type: Function,
+ required: true
+ },
+ submitButtonLabel: {
+ type: String,
+ default () {
+ return this.$t('importer.submit')
+ }
+ },
+ successMessage: {
+ type: String,
+ default () {
+ return this.$t('importer.success')
+ }
+ },
+ errorMessage: {
+ type: String,
+ default () {
+ return this.$t('importer.error')
+ }
+ }
+ },
data () {
return {
file: null,
error: false,
success: false,
- uploading: false
+ submitting: false
}
},
methods: {
@@ -12,16 +36,12 @@ const Importer = {
this.file = this.$refs.input.files[0]
},
submit () {
- this.uploading = true
- this.$store.state.api.backendInteractor.followImport(this.file)
- .then((status) => {
- if (status) {
- this.success = true
- } else {
- this.error = true
- }
- this.uploading = false
- })
+ this.dismiss()
+ this.submitting = true
+ this.submitHandler(this.file)
+ .then(() => { this.success = true })
+ .catch(() => { this.error = true })
+ .finally(() => { this.submitting = false })
},
dismiss () {
this.success = false
diff --git a/src/components/importer/importer.vue b/src/components/importer/importer.vue
index d2447e1a..0c5aa93d 100644
--- a/src/components/importer/importer.vue
+++ b/src/components/importer/importer.vue
@@ -3,15 +3,15 @@
-
-
+
+
-
{{$t('settings.follows_imported')}}
+
{{successMessage}}
-
{{$t('settings.follow_import_error')}}
+
{{errorMessage}}
@@ -20,7 +20,7 @@
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index c4214744..d40301f2 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -14,6 +14,7 @@ import ProgressButton from '../progress_button/progress_button.vue'
import EmojiInput from '../emoji-input/emoji-input.vue'
import Autosuggest from '../autosuggest/autosuggest.vue'
import Importer from '../importer/importer.vue'
+import Exporter from '../exporter/exporter.vue'
import withSubscription from '../../hocs/with_subscription/with_subscription'
import userSearchApi from '../../services/new_api/user_search.js'
@@ -41,7 +42,6 @@ const UserSettings = {
hideFollowers: this.$store.state.users.currentUser.hide_followers,
showRole: this.$store.state.users.currentUser.show_role,
role: this.$store.state.users.currentUser.role,
- enableFollowsExport: true,
pickAvatarBtnVisible: true,
bannerUploading: false,
backgroundUploading: false,
@@ -73,7 +73,8 @@ const UserSettings = {
BlockCard,
MuteCard,
ProgressButton,
- Importer
+ Importer,
+ Exporter
},
computed: {
user () {
@@ -250,38 +251,19 @@ const UserSettings = {
}
})
},
- /* This function takes an Array of Users
- * and outputs a file with all the addresses for the user to download
- */
- 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
- })
+ getFollowsContent () {
+ return this.$store.state.api.backendInteractor.exportFriends({ id: this.$store.state.users.currentUser.id })
.then((friendList) => {
- this.exportPeople(friendList, 'friends.csv')
- setTimeout(() => { this.enableFollowsExport = true }, 2000)
+ // Get all the friends addresses
+ 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 () {
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 520a3d8a..ef77aaba 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -173,12 +173,9 @@
{{$t('settings.import_followers_from_a_csv_file')}}
-
+
{{$t('settings.follow_export')}}
-
-
-
-
{{$t('settings.follow_export_processing')}}
+
{{$t('settings.block_import')}}
diff --git a/src/i18n/en.json b/src/i18n/en.json
index d4ec1134..10283024 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -2,6 +2,10 @@
"chat": {
"title": "Chat"
},
+ "exporter": {
+ "export": "Export",
+ "processing": "Processing, you'll soon be asked to download your file"
+ },
"features_panel": {
"chat": "Chat",
"gopher": "Gopher",
@@ -161,7 +165,6 @@
"filtering_explanation": "All statuses containing these words will be muted, one per line",
"follow_export": "Follow export",
"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_error": "Error importing followers",
"follows_imported": "Follows imported! Processing them will take a while.",
From 13abe64f875220eb5ff5424187bc771acf46190e Mon Sep 17 00:00:00 2001
From: taehoon
Date: Sat, 30 Mar 2019 08:07:49 -0400
Subject: [PATCH 08/11] fix wrong function binding
---
src/components/user_settings/user_settings.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index ef77aaba..db8c1ea9 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -180,7 +180,7 @@
{{$t('settings.block_import')}}
{{$t('settings.import_blocks_from_a_csv_file')}}
-
+
From 95bc2d727b8a94e9050a71c27838eb2a0d765011 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Sat, 30 Mar 2019 08:14:52 -0400
Subject: [PATCH 09/11] =?UTF-8?q?add=20=E2=80=9Cexport=20blocks=E2=80=9D?=
=?UTF-8?q?=20feature?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/user_settings/user_settings.js | 19 +++++++++++++++++--
.../user_settings/user_settings.vue | 4 ++++
src/i18n/en.json | 2 ++
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index d40301f2..de8b4ebf 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -253,9 +253,24 @@ const UserSettings = {
},
getFollowsContent () {
return this.$store.state.api.backendInteractor.exportFriends({ id: this.$store.state.users.currentUser.id })
- .then((friendList) => {
+ .then((users) => {
// Get all the friends addresses
- return friendList.map((user) => {
+ return users.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')
+ })
+ },
+ getBlocksContent () {
+ return this.$store.state.api.backendInteractor.fetchBlocks()
+ .then((users) => {
+ // Get all the friends addresses
+ return users.map((user) => {
// check is it's a local user
if (user && user.is_local) {
// append the instance address
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index db8c1ea9..8a94f0b8 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -182,6 +182,10 @@
{{$t('settings.import_blocks_from_a_csv_file')}}
+
+
{{$t('settings.block_export')}}
+
+
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 10283024..173e0de2 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -135,6 +135,8 @@
"avatarRadius": "Avatars",
"background": "Background",
"bio": "Bio",
+ "block_export": "Block export",
+ "block_export_button": "Export your blocks to a csv file",
"block_import": "Block import",
"block_import_error": "Error importing blocks",
"blocks_imported": "Blocks imported! Processing them will take a while.",
From ab19669bf1470f1e2dfe35cb17e3f748edf4c2d2 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Sat, 30 Mar 2019 08:17:37 -0400
Subject: [PATCH 10/11] refactoring
---
src/components/user_settings/user_settings.js | 38 +++++++------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index de8b4ebf..748f23f7 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -251,35 +251,25 @@ const UserSettings = {
}
})
},
+ generateExportableUsersContent (users) {
+ // Get addresses
+ return users.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')
+ },
getFollowsContent () {
return this.$store.state.api.backendInteractor.exportFriends({ id: this.$store.state.users.currentUser.id })
- .then((users) => {
- // Get all the friends addresses
- return users.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')
- })
+ .then(this.generateExportableUsersContent)
},
getBlocksContent () {
return this.$store.state.api.backendInteractor.fetchBlocks()
- .then((users) => {
- // Get all the friends addresses
- return users.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')
- })
+ .then(this.generateExportableUsersContent)
},
confirmDelete () {
this.deletingAccount = true
From a793835566d478503f4cadf7970ad62476dd75ac Mon Sep 17 00:00:00 2001
From: taehoon
Date: Mon, 29 Apr 2019 13:53:21 -0400
Subject: [PATCH 11/11] add a comment
---
src/components/exporter/exporter.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/exporter/exporter.js b/src/components/exporter/exporter.js
index 2ae9492c..8f507416 100644
--- a/src/components/exporter/exporter.js
+++ b/src/components/exporter/exporter.js
@@ -38,6 +38,7 @@ const Exporter = {
document.body.appendChild(fileToDownload)
fileToDownload.click()
document.body.removeChild(fileToDownload)
+ // Add delay before hiding processing state since browser takes some time to handle file download
setTimeout(() => { this.processing = false }, 2000)
})
}