From f2f3fa81d8b2a077c104702680479671938037c6 Mon Sep 17 00:00:00 2001 From: taehoon Date: Thu, 11 Apr 2019 15:46:44 -0400 Subject: [PATCH 01/24] refer searched user objects from the global user rep --- src/components/user_search/user_search.js | 14 ++++++++++---- src/modules/users.js | 9 +++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/components/user_search/user_search.js b/src/components/user_search/user_search.js index 55040826..62dafdf1 100644 --- a/src/components/user_search/user_search.js +++ b/src/components/user_search/user_search.js @@ -1,5 +1,6 @@ import FollowCard from '../follow_card/follow_card.vue' -import userSearchApi from '../../services/new_api/user_search.js' +import map from 'lodash/map' + const userSearch = { components: { FollowCard @@ -10,10 +11,15 @@ const userSearch = { data () { return { username: '', - users: [], + userIds: [], loading: false } }, + computed: { + users () { + return this.userIds.map(userId => this.$store.getters.findUser(userId)) + } + }, mounted () { this.search(this.query) }, @@ -33,10 +39,10 @@ const userSearch = { return } this.loading = true - userSearchApi.search({query, store: this.$store}) + this.$store.dispatch('searchUsers', query) .then((res) => { this.loading = false - this.users = res + this.userIds = map(res, 'id') }) } } diff --git a/src/modules/users.js b/src/modules/users.js index c98e353a..adcab233 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -1,4 +1,5 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' +import userSearchApi from '../services/new_api/user_search.js' import { compact, map, each, merge, last, concat, uniq } from 'lodash' import { set } from 'vue' import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js' @@ -341,6 +342,14 @@ const users = { store.commit('setUserForNotification', notification) }) }, + searchUsers (store, query) { + // TODO: Move userSearch api into api.service + return userSearchApi.search({query, store: { state: store.rootState }}) + .then((users) => { + store.commit('addNewUsers', users) + return users + }) + }, async signUp (store, userInfo) { store.commit('signUpPending') From 445b54c55310802d561ab1438f8207b59d35d505 Mon Sep 17 00:00:00 2001 From: taehoon Date: Thu, 11 Apr 2019 16:34:46 -0400 Subject: [PATCH 02/24] fix follow button not updating bug in follow-card --- src/components/follow_card/follow_card.js | 15 ++--- src/components/follow_card/follow_card.vue | 60 ++++++++++--------- .../follow_manipulate/follow_manipulate.js | 20 ++----- 3 files changed, 41 insertions(+), 54 deletions(-) diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js index ac4e265a..dc4a0d41 100644 --- a/src/components/follow_card/follow_card.js +++ b/src/components/follow_card/follow_card.js @@ -10,8 +10,7 @@ const FollowCard = { data () { return { inProgress: false, - requestSent: false, - updated: false + requestSent: false } }, components: { @@ -19,10 +18,8 @@ const FollowCard = { RemoteFollow }, computed: { - isMe () { return this.$store.state.users.currentUser.id === this.user.id }, - following () { return this.updated ? this.updated.following : this.user.following }, - showFollow () { - return !this.following || this.updated && !this.updated.following + isMe () { + return this.$store.state.users.currentUser.id === this.user.id }, loggedIn () { return this.$store.state.users.currentUser @@ -31,17 +28,15 @@ const FollowCard = { methods: { followUser () { this.inProgress = true - requestFollow(this.user, this.$store).then(({ sent, updated }) => { + requestFollow(this.user, this.$store).then(({ sent }) => { this.inProgress = false this.requestSent = sent - this.updated = updated }) }, unfollowUser () { this.inProgress = true - requestUnfollow(this.user, this.$store).then(({ updated }) => { + requestUnfollow(this.user, this.$store).then(() => { this.inProgress = false - this.updated = updated }) } } diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue index 9f314fd3..94e2836f 100644 --- a/src/components/follow_card/follow_card.vue +++ b/src/components/follow_card/follow_card.vue @@ -4,34 +4,38 @@ {{ isMe ? $t('user_card.its_you') : $t('user_card.follows_you') }} - - - + + diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js index 51dafe84..b2486e7c 100644 --- a/src/services/follow_manipulate/follow_manipulate.js +++ b/src/services/follow_manipulate/follow_manipulate.js @@ -23,18 +23,12 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => { // For locked users we just mark it that we sent the follow request if (updated.locked) { - resolve({ - sent: true, - updated - }) + resolve({ sent: true }) } if (updated.following) { // If we get result immediately, just stop. - resolve({ - sent: false, - updated - }) + resolve({ sent: false }) } // But usually we don't get result immediately, so we ask server @@ -48,16 +42,10 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => { .then((following) => { if (following) { // We confirmed and everything's good. - resolve({ - sent: false, - updated - }) + resolve({ sent: false }) } else { // If after all the tries, just treat it as if user is locked - resolve({ - sent: false, - updated - }) + resolve({ sent: false }) } }) }) From 55823b8d67e004f7e6f4c1ead59e6a09c049773e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 26 Apr 2019 22:48:21 +0000 Subject: [PATCH 03/24] add BBCode strings --- src/i18n/cs.json | 3 ++- src/i18n/en.json | 3 ++- src/i18n/oc.json | 5 +++-- src/i18n/pl.json | 5 +++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/i18n/cs.json b/src/i18n/cs.json index 020092a6..5f2f2b71 100644 --- a/src/i18n/cs.json +++ b/src/i18n/cs.json @@ -73,7 +73,8 @@ "content_type": { "text/plain": "Prostý text", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Předmět (volitelný)", "default": "Právě jsem přistál v L.A.", diff --git a/src/i18n/en.json b/src/i18n/en.json index 7dca05e3..711e8d31 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -77,7 +77,8 @@ "content_type": { "text/plain": "Plain text", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Subject (optional)", "default": "Just landed in L.A.", diff --git a/src/i18n/oc.json b/src/i18n/oc.json index 83bd97cf..a5826239 100644 --- a/src/i18n/oc.json +++ b/src/i18n/oc.json @@ -77,7 +77,8 @@ "content_type": { "text/plain": "Tèxte brut", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Avís de contengut (opcional)", "default": "Escrivètz aquí vòstre estatut.", @@ -460,4 +461,4 @@ "TiB": "Tio" } } -} \ No newline at end of file +} diff --git a/src/i18n/pl.json b/src/i18n/pl.json index 8efce168..715e5d6e 100644 --- a/src/i18n/pl.json +++ b/src/i18n/pl.json @@ -74,7 +74,8 @@ "content_type": { "text/plain": "Czysty tekst", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Temat (nieobowiązkowy)", "default": "Właśnie wróciłem z kościoła", @@ -431,4 +432,4 @@ "TiB": "TiB" } } -} \ No newline at end of file +} From f4420cbf9f09740e0b6f4f5b4fee4c4df60fcd9a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 27 Apr 2019 04:52:11 +0000 Subject: [PATCH 04/24] entity normalizer: hook up in_reply_to_account_acct --- src/services/entity_normalizer/entity_normalizer.service.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index d68e5a98..e706e7d9 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -195,6 +195,7 @@ export const parseStatus = (data) => { output.summary = pleroma.spoiler_text ? data.pleroma.spoiler_text['text/plain'] : data.spoiler_text output.statusnet_conversation_id = data.pleroma.conversation_id output.is_local = pleroma.local + output.in_reply_to_screen_name = data.pleroma.in_reply_to_account_acct } else { output.text = data.content output.summary = data.spoiler_text @@ -204,8 +205,6 @@ export const parseStatus = (data) => { output.in_reply_to_user_id = data.in_reply_to_account_id output.replies_count = data.replies_count - // Missing!! fix in UI? - // output.in_reply_to_screen_name = ??? if (output.type === 'retweet') { output.retweeted_status = parseStatus(data.reblog) } From 808e1ac11cbbe6779dcaa42d5b4cdec900339ccd Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Mar 2019 13:12:56 -0400 Subject: [PATCH 05/24] Switch to mastoapi for updating avatar # Conflicts: # src/services/api/api.service.js --- src/components/user_settings/user_settings.js | 26 +++++++++-------- src/services/api/api.service.js | 28 ++++++------------- .../backend_interactor_service.js | 2 +- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index e88ee612..1e2422bb 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -164,19 +164,23 @@ const UserSettings = { reader.readAsDataURL(file) }, submitAvatar (cropper, file) { - let img - if (cropper) { - img = cropper.getCroppedCanvas().toDataURL(file.type) - } else { - img = file - } + return new Promise((resolve, reject) => { + function updateAvatar (avatar) { + this.$store.state.api.backendInteractor.updateAvatar({ avatar }) + .then((user) => { + this.$store.commit('addNewUsers', [user]) + this.$store.commit('setCurrentUser', user) + resolve() + }) + .catch((err) => { + reject(new Error(this.$t('upload.error.base') + ' ' + err.message)) + }) + } - return this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { - if (!user.error) { - this.$store.commit('addNewUsers', [user]) - this.$store.commit('setCurrentUser', user) + if (cropper) { + cropper.getCroppedCanvas().toBlob(updateAvatar, file.type) } else { - throw new Error(this.$t('upload.error.base') + user.error) + updateAvatar(file) } }) }, diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 6b255e9f..0540b2d2 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -3,7 +3,6 @@ const LOGIN_URL = '/api/account/verify_credentials.json' const ALL_FOLLOWING_URL = '/api/qvitter/allfollowing' const MENTIONS_URL = '/api/statuses/mentions.json' const REGISTRATION_URL = '/api/account/register.json' -const AVATAR_UPDATE_URL = '/api/qvitter/update_avatar.json' const BG_UPDATE_URL = '/api/qvitter/update_background_image.json' const BANNER_UPDATE_URL = '/api/account/update_profile_banner.json' const PROFILE_UPDATE_URL = '/api/account/update_profile.json' @@ -49,6 +48,7 @@ const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute` const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute` const MASTODON_POST_STATUS_URL = '/api/v1/statuses' const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media' +const MASTODON_PROFILE_UPDATE_URL = '/api/v1/accounts/update_credentials' import { each, map, concat, last } from 'lodash' import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js' @@ -78,28 +78,16 @@ const promisedRequest = (url, options) => { }) } -// Params -// cropH -// cropW -// cropX -// cropY -// img (base 64 encodend data url) -const updateAvatar = ({credentials, params}) => { - let url = AVATAR_UPDATE_URL - +const updateAvatar = ({credentials, avatar}) => { const form = new FormData() - - each(params, (value, key) => { - if (value) { - form.append(key, value) - } - }) - - return fetch(url, { + form.append('avatar', avatar) + return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), - method: 'POST', + method: 'PATCH', body: form - }).then((data) => data.json()) + }) + .then((data) => data.json()) + .then((data) => parseUser(data)) } const updateBg = ({credentials, params}) => { diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 75bba92b..762ee08b 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -101,7 +101,7 @@ const backendInteractorService = (credentials) => { const getCaptcha = () => apiService.getCaptcha() const register = (params) => apiService.register(params) - const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params}) + const updateAvatar = ({avatar}) => apiService.updateAvatar({credentials, avatar}) const updateBg = ({params}) => apiService.updateBg({credentials, params}) const updateBanner = ({params}) => apiService.updateBanner({credentials, params}) const updateProfile = ({params}) => apiService.updateProfile({credentials, params}) From 909d11825d83201bf9ff0ec9491e6361f511ca0f Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Mar 2019 13:56:28 -0400 Subject: [PATCH 06/24] Switch to mastoapi for updating banner --- src/components/user_settings/user_settings.js | 32 ++++++------------- src/services/api/api.service.js | 27 ++++------------ .../backend_interactor_service.js | 2 +- 3 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 1e2422bb..bc824393 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -160,6 +160,7 @@ const UserSettings = { reader.onload = ({target}) => { const img = target.result this[slot + 'Preview'] = img + this[slot] = file } reader.readAsDataURL(file) }, @@ -190,30 +191,17 @@ const UserSettings = { submitBanner () { if (!this.bannerPreview) { return } - let banner = this.bannerPreview - // eslint-disable-next-line no-undef - let imginfo = new Image() - /* eslint-disable camelcase */ - let offset_top, offset_left, width, height - imginfo.src = banner - width = imginfo.width - height = imginfo.height - offset_top = 0 - offset_left = 0 this.bannerUploading = true - this.$store.state.api.backendInteractor.updateBanner({params: {banner, offset_top, offset_left, width, height}}).then((data) => { - if (!data.error) { - let clone = JSON.parse(JSON.stringify(this.$store.state.users.currentUser)) - clone.cover_photo = data.url - this.$store.commit('addNewUsers', [clone]) - this.$store.commit('setCurrentUser', clone) + this.$store.state.api.backendInteractor.updateBanner({banner: this.banner}) + .then((user) => { + this.$store.commit('addNewUsers', [user]) + this.$store.commit('setCurrentUser', user) this.bannerPreview = null - } else { - this.bannerUploadError = this.$t('upload.error.base') + data.error - } - this.bannerUploading = false - }) - /* eslint-enable camelcase */ + }) + .catch((err) => { + this.bannerUploadError = this.$t('upload.error.base') + ' ' + err.message + }) + .then(() => { this.bannerUploading = false }) }, submitBg () { if (!this.backgroundPreview) { return } diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 0540b2d2..eaebb3f1 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -4,7 +4,6 @@ const ALL_FOLLOWING_URL = '/api/qvitter/allfollowing' const MENTIONS_URL = '/api/statuses/mentions.json' const REGISTRATION_URL = '/api/account/register.json' const BG_UPDATE_URL = '/api/qvitter/update_background_image.json' -const BANNER_UPDATE_URL = '/api/account/update_profile_banner.json' const PROFILE_UPDATE_URL = '/api/account/update_profile.json' const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' @@ -108,28 +107,16 @@ const updateBg = ({credentials, params}) => { }).then((data) => data.json()) } -// Params -// height -// width -// offset_left -// offset_top -// banner (base 64 encodend data url) -const updateBanner = ({credentials, params}) => { - let url = BANNER_UPDATE_URL - +const updateBanner = ({credentials, banner}) => { const form = new FormData() - - each(params, (value, key) => { - if (value) { - form.append(key, value) - } - }) - - return fetch(url, { + form.append('header', banner) + return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), - method: 'POST', + method: 'PATCH', body: form - }).then((data) => data.json()) + }) + .then((data) => data.json()) + .then((data) => parseUser(data)) } // Params diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 762ee08b..d61ff452 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -103,7 +103,7 @@ const backendInteractorService = (credentials) => { const register = (params) => apiService.register(params) const updateAvatar = ({avatar}) => apiService.updateAvatar({credentials, avatar}) const updateBg = ({params}) => apiService.updateBg({credentials, params}) - const updateBanner = ({params}) => apiService.updateBanner({credentials, params}) + const updateBanner = ({banner}) => apiService.updateBanner({credentials, banner}) const updateProfile = ({params}) => apiService.updateProfile({credentials, params}) const externalProfile = (profileUrl) => apiService.externalProfile({profileUrl, credentials}) From e14720419f743f630eec8a671833eb08923e3dee Mon Sep 17 00:00:00 2001 From: taehoon Date: Sat, 16 Mar 2019 08:40:46 -0400 Subject: [PATCH 07/24] Switch to mastoapi for updating user profile --- src/components/user_settings/user_settings.js | 14 ++++++-------- src/services/api/api.service.js | 13 ++++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index bc824393..6b367e4f 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -110,11 +110,11 @@ const UserSettings = { }, methods: { updateProfile () { - const name = this.newName - const description = this.newBio + const note = this.newBio const locked = this.newLocked // Backend notation. /* eslint-disable camelcase */ + const display_name = this.newName const default_scope = this.newDefaultScope const no_rich_text = this.newNoRichText const hide_follows = this.hideFollows @@ -125,8 +125,8 @@ const UserSettings = { this.$store.state.api.backendInteractor .updateProfile({ params: { - name, - description, + display_name, + note, locked, // Backend notation. /* eslint-disable camelcase */ @@ -137,10 +137,8 @@ const UserSettings = { show_role /* eslint-enable camelcase */ }}).then((user) => { - if (!user.error) { - this.$store.commit('addNewUsers', [user]) - this.$store.commit('setCurrentUser', user) - } + this.$store.commit('addNewUsers', [user]) + this.$store.commit('setCurrentUser', user) }) }, changeVis (visibility) { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index eaebb3f1..9338c495 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -4,7 +4,6 @@ const ALL_FOLLOWING_URL = '/api/qvitter/allfollowing' const MENTIONS_URL = '/api/statuses/mentions.json' const REGISTRATION_URL = '/api/account/register.json' const BG_UPDATE_URL = '/api/qvitter/update_background_image.json' -const PROFILE_UPDATE_URL = '/api/account/update_profile.json' const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import' @@ -126,9 +125,7 @@ const updateBanner = ({credentials, banner}) => { // description const updateProfile = ({credentials, params}) => { // Always include these fields, because they might be empty or false - const fields = ['description', 'locked', 'no_rich_text', 'hide_follows', 'hide_followers', 'show_role'] - let url = PROFILE_UPDATE_URL - + const fields = ['note', 'locked', 'no_rich_text', 'hide_follows', 'hide_followers', 'show_role'] const form = new FormData() each(params, (value, key) => { @@ -136,11 +133,13 @@ const updateProfile = ({credentials, params}) => { form.append(key, value) } }) - return fetch(url, { + return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), - method: 'POST', + method: 'PATCH', body: form - }).then((data) => data.json()) + }) + .then((data) => data.json()) + .then((data) => parseUser(data)) } // Params needed: From ac0b45fa149dad9be84074313b69b9f3d360928a Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 22 Mar 2019 13:00:58 -0400 Subject: [PATCH 08/24] Update avatar uploading --- src/components/image_cropper/image_cropper.js | 16 ++-------------- src/components/image_cropper/image_cropper.vue | 4 ++-- src/components/user_settings/user_settings.js | 9 +++++---- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js index 5ba8f04e..01361e25 100644 --- a/src/components/image_cropper/image_cropper.js +++ b/src/components/image_cropper/image_cropper.js @@ -70,22 +70,10 @@ const ImageCropper = { this.dataUrl = undefined this.$emit('close') }, - submit () { + submit (cropping = true) { this.submitting = true this.avatarUploadError = null - this.submitHandler(this.cropper, this.file) - .then(() => this.destroy()) - .catch((err) => { - this.submitError = err - }) - .finally(() => { - this.submitting = false - }) - }, - submitWithoutCropping () { - this.submitting = true - this.avatarUploadError = null - this.submitHandler(false, this.dataUrl) + this.submitHandler(cropping && this.cropper, this.file) .then(() => this.destroy()) .catch((err) => { this.submitError = err diff --git a/src/components/image_cropper/image_cropper.vue b/src/components/image_cropper/image_cropper.vue index 129e6f46..d2b86e9e 100644 --- a/src/components/image_cropper/image_cropper.vue +++ b/src/components/image_cropper/image_cropper.vue @@ -5,9 +5,9 @@
- + - +
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 6b367e4f..820feba6 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -163,16 +163,17 @@ const UserSettings = { reader.readAsDataURL(file) }, submitAvatar (cropper, file) { + const that = this return new Promise((resolve, reject) => { function updateAvatar (avatar) { - this.$store.state.api.backendInteractor.updateAvatar({ avatar }) + that.$store.state.api.backendInteractor.updateAvatar({ avatar }) .then((user) => { - this.$store.commit('addNewUsers', [user]) - this.$store.commit('setCurrentUser', user) + that.$store.commit('addNewUsers', [user]) + that.$store.commit('setCurrentUser', user) resolve() }) .catch((err) => { - reject(new Error(this.$t('upload.error.base') + ' ' + err.message)) + reject(new Error(that.$t('upload.error.base') + ' ' + err.message)) }) } From 562120ae48945d87a24f2248f9b16185b49159d0 Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 29 Mar 2019 21:58:20 -0400 Subject: [PATCH 09/24] =?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 @@ + + + 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 10/24] 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 11/24] 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 12/24] 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 16/24] 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 17/24] =?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 18/24] 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 2c4af6693ac87f5008566b6d9a61e9b4c9b3bdd8 Mon Sep 17 00:00:00 2001 From: taehoon Date: Sat, 27 Apr 2019 14:04:30 -0400 Subject: [PATCH 19/24] clean up --- src/components/user_settings/user_settings.js | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 820feba6..ae4d0694 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -110,31 +110,21 @@ const UserSettings = { }, methods: { updateProfile () { - const note = this.newBio - const locked = this.newLocked - // Backend notation. - /* eslint-disable camelcase */ - const display_name = this.newName - const default_scope = this.newDefaultScope - const no_rich_text = this.newNoRichText - const hide_follows = this.hideFollows - const hide_followers = this.hideFollowers - const show_role = this.showRole - - /* eslint-enable camelcase */ this.$store.state.api.backendInteractor .updateProfile({ params: { - display_name, - note, - locked, + note: this.newBio, + locked: this.newLocked, + source: { + privacy: this.newDefaultScope + }, // Backend notation. /* eslint-disable camelcase */ - default_scope, - no_rich_text, - hide_follows, - hide_followers, - show_role + display_name: this.newName, + no_rich_text: this.newNoRichText, + hide_follows: this.hideFollows, + hide_followers: this.hideFollowers, + show_role: this.showRole /* eslint-enable camelcase */ }}).then((user) => { this.$store.commit('addNewUsers', [user]) From 904a64de8951356d0e1a798349661039d5821d32 Mon Sep 17 00:00:00 2001 From: taehoon Date: Sat, 27 Apr 2019 14:20:32 -0400 Subject: [PATCH 20/24] use json content type --- src/services/api/api.service.js | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 9338c495..1cf47bb8 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -118,27 +118,16 @@ const updateBanner = ({credentials, banner}) => { .then((data) => parseUser(data)) } -// Params -// name -// url -// location -// description const updateProfile = ({credentials, params}) => { - // Always include these fields, because they might be empty or false - const fields = ['note', 'locked', 'no_rich_text', 'hide_follows', 'hide_followers', 'show_role'] - const form = new FormData() - - each(params, (value, key) => { - if (fields.includes(key) || value) { - form.append(key, value) - } - }) - return fetch(MASTODON_PROFILE_UPDATE_URL, { - headers: authHeaders(credentials), + return promisedRequest(MASTODON_PROFILE_UPDATE_URL, { + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + ...authHeaders(credentials) + }, method: 'PATCH', - body: form + body: JSON.stringify(params) }) - .then((data) => data.json()) .then((data) => parseUser(data)) } From 3665c86d709f3a04ae3471d09b84a69c8a8c9172 Mon Sep 17 00:00:00 2001 From: taehoon Date: Sat, 27 Apr 2019 21:51:17 -0400 Subject: [PATCH 21/24] use default_scope parameter --- src/components/user_settings/user_settings.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index ae4d0694..5a7ff448 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -115,12 +115,10 @@ const UserSettings = { params: { note: this.newBio, locked: this.newLocked, - source: { - privacy: this.newDefaultScope - }, // Backend notation. /* eslint-disable camelcase */ display_name: this.newName, + default_scope: this.newDefaultScope, no_rich_text: this.newNoRichText, hide_follows: this.hideFollows, hide_followers: this.hideFollowers, From b1f8221a0af1d7eb37e5a5305e2ca6e9d40a268f Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 29 Apr 2019 13:20:03 -0400 Subject: [PATCH 22/24] show ellipsis for long user name and screen name --- .../basic_user_card/basic_user_card.vue | 15 ++++++++------- .../selectable_list/selectable_list.vue | 4 ++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue index 48de6678..25f1fb2a 100644 --- a/src/components/basic_user_card/basic_user_card.vue +++ b/src/components/basic_user_card/basic_user_card.vue @@ -44,14 +44,15 @@ width: 16px; vertical-align: middle; } + } - &-value { - display: inline-block; - max-width: 100%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } + &-user-name-value, + &-screen-name { + display: inline-block; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } &-expanded-content { diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue index ba1e5266..81305a5e 100644 --- a/src/components/selectable_list/selectable_list.vue +++ b/src/components/selectable_list/selectable_list.vue @@ -31,6 +31,10 @@ &-item-inner { display: flex; align-items: center; + + & > * { + min-width: 0; + } } &-item-selected-inner { From a793835566d478503f4cadf7970ad62476dd75ac Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 29 Apr 2019 13:53:21 -0400 Subject: [PATCH 23/24] 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) }) } From 5b16e368285a3e61f8d200c06e6109ec39819314 Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 29 Apr 2019 13:57:44 -0400 Subject: [PATCH 24/24] remove & --- src/components/selectable_list/selectable_list.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue index 81305a5e..3f16c921 100644 --- a/src/components/selectable_list/selectable_list.vue +++ b/src/components/selectable_list/selectable_list.vue @@ -32,7 +32,7 @@ display: flex; align-items: center; - & > * { + > * { min-width: 0; } }