diff --git a/src/App.scss b/src/App.scss index 5355d8998..871f193fb 100644 --- a/src/App.scss +++ b/src/App.scss @@ -228,24 +228,23 @@ i[class*=icon-] { padding: 0 10px 0 10px; } -.gaps { - margin: -1em 0 0 -1em; -} - .item { flex: 1; line-height: 50px; height: 50px; overflow: hidden; + display: flex; + flex-wrap: wrap; .nav-icon { font-size: 1.1em; margin-left: 0.4em; } -} -.gaps > .item { - padding: 1em 0 0 1em; + &.right { + justify-content: right; + padding-right: 20px; + } } .auto-size { @@ -293,8 +292,6 @@ nav { } .inner-nav { - padding-left: 20px; - padding-right: 20px; display: flex; align-items: center; flex-basis: 970px; @@ -452,6 +449,23 @@ nav { color: var(--faint, $fallback--faint); box-shadow: 0px 0px 4px rgba(0,0,0,.6); box-shadow: var(--topBarShadow); + + .back-button { + display: block; + max-width: 99px; + transition-property: opacity, max-width; + transition-duration: 300ms; + transition-timing-function: ease-out; + + i { + margin: 0 1em; + } + + &.hidden { + opacity: 0; + max-width: 20px; + } + } } .fade-enter-active, .fade-leave-active { @@ -486,6 +500,7 @@ nav { display: none; width: 100%; height: 46px; + button { display: block; flex: 1; @@ -499,6 +514,16 @@ nav { body { overflow-y: scroll; } + + nav { + .back-button { + display: none; + } + .site-name { + padding-left: 20px; + } + } + .sidebar-bounds { overflow: hidden; max-height: 100vh; @@ -591,11 +616,6 @@ nav { } } -.item.right { - text-align: right; - padding-right: 20px; -} - .visibility-tray { font-size: 1.2em; padding: 3px; diff --git a/src/App.vue b/src/App.vue index 16cd08d47..048c1e77d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,7 +7,10 @@
- {{sitename}} + + + + {{sitename}}
diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 07337595f..24a8d3ac2 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -21,13 +21,21 @@ const afterStoreSetup = ({ store, i18n }) => { window.fetch('/api/statusnet/config.json') .then((res) => res.json()) .then((data) => { - const { name, closed: registrationClosed, textlimit, server, vapidPublicKey } = data.site + const { name, closed: registrationClosed, textlimit, uploadlimit, server, vapidPublicKey } = data.site store.dispatch('setInstanceOption', { name: 'name', value: name }) store.dispatch('setInstanceOption', { name: 'registrationOpen', value: (registrationClosed === '0') }) store.dispatch('setInstanceOption', { name: 'textlimit', value: parseInt(textlimit) }) + store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadlimit.uploadlimit) }) + store.dispatch('setInstanceOption', { name: 'avatarlimit', value: parseInt(uploadlimit.avatarlimit) }) + store.dispatch('setInstanceOption', { name: 'backgroundlimit', value: parseInt(uploadlimit.backgroundlimit) }) + store.dispatch('setInstanceOption', { name: 'bannerlimit', value: parseInt(uploadlimit.bannerlimit) }) store.dispatch('setInstanceOption', { name: 'server', value: server }) + if (data.nsfwCensorImage) { + store.dispatch('setInstanceOption', { name: 'nsfwCensorImage', value: data.nsfwCensorImage }) + } + if (vapidPublicKey) { store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey }) } diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js index 16114c30c..97c4f283f 100644 --- a/src/components/attachment/attachment.js +++ b/src/components/attachment/attachment.js @@ -11,7 +11,7 @@ const Attachment = { ], data () { return { - nsfwImage, + nsfwImage: this.$store.state.config.nsfwCensorImage || nsfwImage, hideNsfwLocal: this.$store.state.config.hideNsfw, preloadImage: this.$store.state.config.preloadImage, loopVideo: this.$store.state.config.loopVideo, diff --git a/src/components/media_upload/media_upload.js b/src/components/media_upload/media_upload.js index 66337c3f8..42d900d35 100644 --- a/src/components/media_upload/media_upload.js +++ b/src/components/media_upload/media_upload.js @@ -1,5 +1,6 @@ /* eslint-env browser */ import statusPosterService from '../../services/status_poster/status_poster.service.js' +import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' const mediaUpload = { mounted () { @@ -21,6 +22,12 @@ const mediaUpload = { uploadFile (file) { const self = this const store = this.$store + if (file.size > store.state.instance.uploadlimit) { + const filesize = fileSizeFormatService.fileSizeFormat(file.size) + const allowedsize = fileSizeFormatService.fileSizeFormat(store.state.instance.uploadlimit) + self.$emit('upload-failed', 'file_too_big', {filesize: filesize.num, filesizeunit: filesize.unit, allowedsize: allowedsize.num, allowedsizeunit: allowedsize.unit}) + return + } const formData = new FormData() formData.append('media', file) @@ -32,7 +39,7 @@ const mediaUpload = { self.$emit('uploaded', fileData) self.uploading = false }, (error) => { // eslint-disable-line handle-callback-err - self.$emit('upload-failed') + self.$emit('upload-failed', 'default') self.uploading = false }) }, diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index e3d6e91d3..48fd681ad 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -259,6 +259,11 @@ const PostStatusForm = { let index = this.newStatus.files.indexOf(fileInfo) this.newStatus.files.splice(index, 1) }, + uploadFailed (errString, templateArgs) { + templateArgs = templateArgs || {} + this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs) + this.enableSubmit() + }, disableSubmit () { this.submitDisabled = true }, diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index fcf5c873c..4776c8190 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -64,7 +64,7 @@
- +

{{ charactersLeft }}

{{ charactersLeft }}

diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index a651f619b..f28b85bdd 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -2,6 +2,7 @@ import Status from '../status/status.vue' import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js' import StatusOrConversation from '../status_or_conversation/status_or_conversation.vue' import UserCard from '../user_card/user_card.vue' +import { throttle } from 'lodash' const Timeline = { props: [ @@ -88,7 +89,7 @@ const Timeline = { this.paused = false } }, - fetchOlderStatuses () { + fetchOlderStatuses: throttle(function () { const store = this.$store const credentials = store.state.users.currentUser.credentials store.commit('setLoading', { timeline: this.timelineName, value: true }) @@ -101,7 +102,7 @@ const Timeline = { userId: this.userId, tag: this.tag }).then(() => store.commit('setLoading', { timeline: this.timelineName, value: false })) - }, + }, 1000, this), fetchFollowers () { const id = this.userId this.$store.state.api.backendInteractor.fetchFollowers({ id }) diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index a019627a8..b8eb28e3d 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -14,6 +14,9 @@ const UserCard = { components: { UserCardContent }, + computed: { + currentUser () { return this.$store.state.users.currentUser } + }, methods: { toggleUserExpanded () { this.userExpanded = !this.userExpanded diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 5a8e55319..eb0d7576c 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -10,13 +10,13 @@
- {{ $t('user_card.follows_you') }} + {{ currentUser.id == user.id ? $t('user_card.its_you') : $t('user_card.follows_you') }}
{{ user.name }} - {{ $t('user_card.follows_you') }} + {{ currentUser.id == user.id ? $t('user_card.its_you') : $t('user_card.follows_you') }}
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js index e7f199536..be7a23492 100644 --- a/src/components/user_card_content/user_card_content.js +++ b/src/components/user_card_content/user_card_content.js @@ -20,10 +20,20 @@ export default { if (color) { const rgb = (typeof color === 'string') ? hex2rgb(color) : color const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)` + + const gradient = [ + [tintColor, this.hideBio ? '60%' : ''], + this.hideBio ? [ + color, '100%' + ] : [ + tintColor, '' + ] + ].map(_ => _.join(' ')).join(', ') + return { backgroundColor: `rgb(${Math.floor(rgb.r * 0.53)}, ${Math.floor(rgb.g * 0.56)}, ${Math.floor(rgb.b * 0.59)})`, backgroundImage: [ - `linear-gradient(to bottom, ${tintColor}, ${tintColor})`, + `linear-gradient(to bottom, ${gradient})`, `url(${this.user.cover_photo})` ].join(', ') } diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index 185042776..08b255956 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -90,7 +90,7 @@
-
+
{{ $t('user_card.statuses') }}
@@ -122,6 +122,9 @@ border-radius: var(--panelRadius, $fallback--panelRadius); overflow: hidden; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + .panel-heading { padding: 0.6em 0em; text-align: center; diff --git a/src/components/user_finder/user_finder.vue b/src/components/user_finder/user_finder.vue index 8786f6c76..4d9f68420 100644 --- a/src/components/user_finder/user_finder.vue +++ b/src/components/user_finder/user_finder.vue @@ -1,12 +1,12 @@ @@ -15,7 +15,6 @@ @import '../../_variables.scss'; .user-finder-container { - height: 29px; max-width: 100%; } diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index 91d4acd29..4d2853a63 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -3,6 +3,16 @@ +
@@ -21,4 +31,12 @@ align-items: stretch; } } +.user-profile-placeholder { + .panel-body { + display: flex; + justify-content: center; + align-items: middle; + padding: 7em; + } +} diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 761e674ad..ca7bf319a 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -1,20 +1,30 @@ import TabSwitcher from '../tab_switcher/tab_switcher.jsx' import StyleSwitcher from '../style_switcher/style_switcher.vue' +import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' const UserSettings = { data () { return { - newname: this.$store.state.users.currentUser.name, - newbio: this.$store.state.users.currentUser.description, - newlocked: this.$store.state.users.currentUser.locked, - newnorichtext: this.$store.state.users.currentUser.no_rich_text, - newdefaultScope: this.$store.state.users.currentUser.default_scope, + newName: this.$store.state.users.currentUser.name, + newBio: this.$store.state.users.currentUser.description, + newLocked: this.$store.state.users.currentUser.locked, + newNoRichText: this.$store.state.users.currentUser.no_rich_text, + newDefaultScope: this.$store.state.users.currentUser.default_scope, + newHideNetwork: this.$store.state.users.currentUser.hide_network, followList: null, followImportError: false, followsImported: false, enableFollowsExport: true, - uploading: [ false, false, false, false ], - previews: [ null, null, null ], + avatarUploading: false, + bannerUploading: false, + backgroundUploading: false, + followListUploading: false, + avatarPreview: null, + bannerPreview: null, + backgroundPreview: null, + avatarUploadError: null, + bannerUploadError: null, + backgroundUploadError: null, deletingAccount: false, deleteAccountConfirmPasswordInput: '', deleteAccountError: false, @@ -40,48 +50,67 @@ const UserSettings = { }, vis () { return { - public: { selected: this.newdefaultScope === 'public' }, - unlisted: { selected: this.newdefaultScope === 'unlisted' }, - private: { selected: this.newdefaultScope === 'private' }, - direct: { selected: this.newdefaultScope === 'direct' } + public: { selected: this.newDefaultScope === 'public' }, + unlisted: { selected: this.newDefaultScope === 'unlisted' }, + private: { selected: this.newDefaultScope === 'private' }, + direct: { selected: this.newDefaultScope === 'direct' } } } }, methods: { updateProfile () { const name = this.newname - const description = this.newbio - const locked = this.newlocked + const description = this.newBio + const locked = this.newLocked + // Backend notation. /* eslint-disable camelcase */ - const default_scope = this.newdefaultScope - const no_rich_text = this.newnorichtext - this.$store.state.api.backendInteractor.updateProfile({params: {name, description, locked, default_scope, no_rich_text}}).then((user) => { - if (!user.error) { - this.$store.commit('addNewUsers', [user]) - this.$store.commit('setCurrentUser', user) - } - }) + const default_scope = this.newDefaultScope + const no_rich_text = this.newNoRichText + const hide_network = this.newHideNetwork /* eslint-enable camelcase */ + this.$store.state.api.backendInteractor + .updateProfile({ + params: { + name, + description, + locked, + // Backend notation. + /* eslint-disable camelcase */ + default_scope, + no_rich_text, + hide_network + /* eslint-enable camelcase */ + }}).then((user) => { + if (!user.error) { + this.$store.commit('addNewUsers', [user]) + this.$store.commit('setCurrentUser', user) + } + }) }, changeVis (visibility) { - this.newdefaultScope = visibility + this.newDefaultScope = visibility }, uploadFile (slot, e) { const file = e.target.files[0] if (!file) { return } + if (file.size > this.$store.state.instance[slot + 'limit']) { + const filesize = fileSizeFormatService.fileSizeFormat(file.size) + const allowedsize = fileSizeFormatService.fileSizeFormat(this.$store.state.instance[slot + 'limit']) + this[slot + 'UploadError'] = this.$t('upload.error.base') + ' ' + this.$t('upload.error.file_too_big', {filesize: filesize.num, filesizeunit: filesize.unit, allowedsize: allowedsize.num, allowedsizeunit: allowedsize.unit}) + return + } // eslint-disable-next-line no-undef const reader = new FileReader() reader.onload = ({target}) => { const img = target.result - this.previews[slot] = img - this.$forceUpdate() // just changing the array with the index doesn't update the view + this[slot + 'Preview'] = img } reader.readAsDataURL(file) }, submitAvatar () { - if (!this.previews[0]) { return } + if (!this.avatarPreview) { return } - let img = this.previews[0] + let img = this.avatarPreview // eslint-disable-next-line no-undef let imginfo = new Image() let cropX, cropY, cropW, cropH @@ -97,20 +126,25 @@ const UserSettings = { cropX = Math.floor((imginfo.width - imginfo.height) / 2) cropW = imginfo.height } - this.uploading[0] = true + this.avatarUploading = true this.$store.state.api.backendInteractor.updateAvatar({params: {img, cropX, cropY, cropW, cropH}}).then((user) => { if (!user.error) { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) - this.previews[0] = null + this.avatarPreview = null + } else { + this.avatarUploadError = this.$t('upload.error.base') + user.error } - this.uploading[0] = false + this.avatarUploading = false }) }, + clearUploadError (slot) { + this[slot + 'UploadError'] = null + }, submitBanner () { - if (!this.previews[1]) { return } + if (!this.bannerPreview) { return } - let banner = this.previews[1] + let banner = this.bannerPreview // eslint-disable-next-line no-undef let imginfo = new Image() /* eslint-disable camelcase */ @@ -120,22 +154,24 @@ const UserSettings = { height = imginfo.height offset_top = 0 offset_left = 0 - this.uploading[1] = true + 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.previews[1] = null + this.bannerPreview = null + } else { + this.bannerUploadError = this.$t('upload.error.base') + data.error } - this.uploading[1] = false + this.bannerUploading = false }) /* eslint-enable camelcase */ }, submitBg () { - if (!this.previews[2]) { return } - let img = this.previews[2] + if (!this.backgroundPreview) { return } + let img = this.backgroundPreview // eslint-disable-next-line no-undef let imginfo = new Image() let cropX, cropY, cropW, cropH @@ -144,20 +180,22 @@ const UserSettings = { cropY = 0 cropW = imginfo.width cropH = imginfo.width - this.uploading[2] = true + this.backgroundUploading = true this.$store.state.api.backendInteractor.updateBg({params: {img, cropX, cropY, cropW, cropH}}).then((data) => { if (!data.error) { let clone = JSON.parse(JSON.stringify(this.$store.state.users.currentUser)) clone.background_image = data.url this.$store.commit('addNewUsers', [clone]) this.$store.commit('setCurrentUser', clone) - this.previews[2] = null + this.backgroundPreview = null + } else { + this.backgroundUploadError = this.$t('upload.error.base') + data.error } - this.uploading[2] = false + this.backgroundUploading = false }) }, importFollows () { - this.uploading[3] = true + this.followListUploading = true const followList = this.followList this.$store.state.api.backendInteractor.followImport({params: followList}) .then((status) => { @@ -166,7 +204,7 @@ const UserSettings = { } else { this.followImportError = true } - this.uploading[3] = false + this.followListUploading = false }) }, /* This function takes an Array of Users @@ -198,6 +236,7 @@ const UserSettings = { .fetchFriends({id: this.$store.state.users.currentUser.id}) .then((friendList) => { this.exportPeople(friendList, 'friends.csv') + setTimeout(() => { this.enableFollowsExport = true }, 2000) }) }, followListChange () { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 234a7d862..67b65b574 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -9,11 +9,11 @@

{{$t('settings.name_bio')}}

{{$t('settings.name')}}

- +

{{$t('settings.bio')}}

- +

- +

@@ -26,47 +26,63 @@

- +

- +

+ + +

+

{{$t('settings.avatar')}}

{{$t('settings.current_avatar')}}

{{$t('settings.set_new_avatar')}}

- +
- + +
+ + +
+ Error: {{ avatarUploadError }} +
- -

{{$t('settings.profile_banner')}}

{{$t('settings.current_profile_banner')}}

{{$t('settings.set_new_profile_banner')}}

- +
- + +
+ + +
+ Error: {{ bannerUploadError }} +
- -

{{$t('settings.profile_background')}}

{{$t('settings.set_new_profile_background')}}

- +
- + +
+ + +
+ Error: {{ backgroundUploadError }} +
- -
@@ -113,7 +129,7 @@
- +
diff --git a/src/i18n/en.json b/src/i18n/en.json index eebf606ae..1ce537963 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -29,6 +29,7 @@ "username": "Username" }, "nav": { + "back": "Back", "chat": "Local Chat", "friend_requests": "Follow Requests", "mentions": "Mentions", @@ -151,6 +152,7 @@ "notification_visibility_mentions": "Mentions", "notification_visibility_repeats": "Repeats", "no_rich_text_description": "Strip rich text formatting from all posts", + "hide_network_description": "Don't show who I'm following and who's following me", "nsfw_clickthrough": "Enable clickthrough NSFW attachment hiding", "panelRadius": "Panels", "pause_on_unfocused": "Pause streaming when tab is not focused", @@ -322,6 +324,7 @@ "followers": "Followers", "following": "Following!", "follows_you": "Follows you!", + "its_you": "It's you!", "mute": "Mute", "muted": "Muted", "per_day": "per day", @@ -341,5 +344,19 @@ "reply": "Reply", "favorite": "Favorite", "user_settings": "User Settings" + }, + "upload":{ + "error": { + "base": "Upload failed.", + "file_too_big": "File too big [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]", + "default": "Try again later" + }, + "file_size_units": { + "B": "B", + "KiB": "KiB", + "MiB": "MiB", + "GiB": "GiB", + "TiB": "TiB" + } } } diff --git a/src/i18n/ru.json b/src/i18n/ru.json index c764005a5..80598b0ce 100644 --- a/src/i18n/ru.json +++ b/src/i18n/ru.json @@ -19,6 +19,7 @@ "username": "Имя пользователя" }, "nav": { + "back": "Назад", "chat": "Локальный чат", "mentions": "Упоминания", "public_tl": "Публичная лента", @@ -126,6 +127,7 @@ "notification_visibility_mentions": "Упоминания", "notification_visibility_repeats": "Повторы", "no_rich_text_description": "Убрать форматирование из всех постов", + "hide_network_description": "Не показывать кого я читаю и кто меня читает", "nsfw_clickthrough": "Включить скрытие NSFW вложений", "panelRadius": "Панели", "pause_on_unfocused": "Приостановить загрузку когда вкладка не в фокусе", diff --git a/src/modules/instance.js b/src/modules/instance.js index 7c27d52ad..ab88306f3 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -25,6 +25,8 @@ const defaultState = { scopeCopy: true, subjectLineBehavior: 'email', loginMethod: 'password', + nsfwCensorImage: undefined, + vapidPublicKey: undefined, // Nasty stuff pleromaBackend: true, diff --git a/src/modules/users.js b/src/modules/users.js index d2ac95cd4..25d1c81f3 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -17,6 +17,9 @@ export const mergeOrAdd = (arr, obj, item) => { // This is a new item, prepare it arr.push(item) obj[item.id] = item + if (item.screen_name && !item.screen_name.includes('@')) { + obj[item.screen_name] = item + } return { item, new: true } } } @@ -87,7 +90,7 @@ const users = { actions: { fetchUser (store, id) { store.rootState.api.backendInteractor.fetchUser({ id }) - .then((user) => store.commit('addNewUsers', user)) + .then((user) => store.commit('addNewUsers', [user])) }, registerPushNotifications (store) { const token = store.state.currentUser.credentials diff --git a/src/services/file_size_format/file_size_format.js b/src/services/file_size_format/file_size_format.js new file mode 100644 index 000000000..add56ee03 --- /dev/null +++ b/src/services/file_size_format/file_size_format.js @@ -0,0 +1,17 @@ +const fileSizeFormat = (num) => { + var exponent + var unit + var units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'] + if (num < 1) { + return num + ' ' + units[0] + } + + exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1) + num = (num / Math.pow(1024, exponent)).toFixed(2) * 1 + unit = units[exponent] + return {num: num, unit: unit} +} +const fileSizeFormatService = { + fileSizeFormat +} +export default fileSizeFormatService diff --git a/test/unit/specs/services/file_size_format/file_size_format.spec.js b/test/unit/specs/services/file_size_format/file_size_format.spec.js new file mode 100644 index 000000000..0a5a82b7f --- /dev/null +++ b/test/unit/specs/services/file_size_format/file_size_format.spec.js @@ -0,0 +1,34 @@ + import fileSizeFormatService from '../../../../../src/services/file_size_format/file_size_format.js' + describe('fileSizeFormat', () => { + it('Formats file size', () => { + const values = [1, 1024, 1048576, 1073741824, 1099511627776] + const expected = [ + { + num: 1, + unit: 'B' + }, + { + num: 1, + unit: 'KiB' + }, + { + num: 1, + unit: 'MiB' + }, + { + num: 1, + unit: 'GiB' + }, + { + num: 1, + unit: 'TiB' + } + ] + + var res = [] + for (var value in values) { + res.push(fileSizeFormatService.fileSizeFormat(values[value])) + } + expect(res).to.eql(expected) + }) + })