Skip to content

Commit

Permalink
Merge branch 'AP-1371' of github.com:Satellite-im/Core-PWA into AP-1371
Browse files Browse the repository at this point in the history
  • Loading branch information
stavares843 committed Apr 20, 2022
2 parents af84365 + c1d9687 commit 8c452b6
Show file tree
Hide file tree
Showing 21 changed files with 172 additions and 103 deletions.
3 changes: 2 additions & 1 deletion components/views/chat/enhancers/Enhancers.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
left: calculatePositionOnScreen(ui.enhancers.position[0]) + 'px',
bottom: ui.enhancers.position[1] + 'px'
} : {}"
@click.stop
>
<div class="navbar" @click="navbarClickHandler">
<div class="navbar"">
<InteractablesButtonGroup
v-model="route"
:fullWidth="true"
Expand Down
15 changes: 0 additions & 15 deletions components/views/chat/enhancers/Enhancers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,6 @@ export default Vue.extend({
}, 0)
})
},
/**
* @method navbarClickHandler
* @description Without this handler user can click on the navbar padding and emojis will disappear
*/
navbarClickHandler(event: Event) {
const target = event.target as Element
const button = target.closest('button')
if (!button) {
this.openEmoji()
}
},
/**
* Adds emoji to current text input
* (emoji: any) Comes from <picker/> select event
*/
/**
* @method addEmoji
* @description Adds emoji to either the users current chatbar or a messages emoji reactions depending on state of this.ui.settingReaction.status
Expand Down
8 changes: 6 additions & 2 deletions components/views/files/controls/Controls.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@
multiple
/>
</div>
<TypographyText v-if="status" class="status" :text="status" :size="6" />
<UiProgress v-if="progress < 100" :progress="progress" />
<TypographyText
v-if="ui.filesUploadStatus"
class="status"
:text="ui.filesUploadStatus"
:size="6"
/>
<div class="error-container" v-if="errors.length">
<alert-triangle-icon size="1.3x" />
<div>
Expand Down
3 changes: 1 addition & 2 deletions components/views/files/controls/Controls.less
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
}
}

.status,
.progress {
.status {
margin-bottom: @normal-spacing;
}

Expand Down
24 changes: 17 additions & 7 deletions components/views/files/controls/Controls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ export default Vue.extend({
return {
text: '' as string,
errors: [] as Array<string | TranslateResult>,
status: '' as string | TranslateResult,
progress: 100 as number,
}
},
computed: {
Expand Down Expand Up @@ -151,7 +149,10 @@ export default Vue.extend({
}
for (const file of files) {
try {
this.status = this.$t('pages.files.controls.upload', [file.name])
this.$store.commit(
'ui/setFilesUploadStatus',
this.$t('pages.files.controls.upload', [file.name]),
)
await this.$FileSystem.uploadFile(file, this.setProgress)
} catch (e: any) {
this.errors.push(e?.message ?? '')
Expand All @@ -160,12 +161,15 @@ export default Vue.extend({
// only update index if files have been updated
if (files.length) {
this.status = this.$t('pages.files.controls.index')
this.$store.commit(
'ui/setFilesUploadStatus',
this.$t('pages.files.controls.index'),
)
await this.$TextileManager.bucket?.updateIndex(this.$FileSystem.export)
}
this.$store.commit('ui/setIsLoadingFileIndex', false)
this.status = ''
this.$store.commit('ui/setFilesUploadStatus', '')
// re-render so new files show up
this.$emit('forceRender')
Expand All @@ -186,11 +190,17 @@ export default Vue.extend({
/**
* @method setProgress
* @description set progress (% out of 100) while file is being pushed to textile bucket. passed as a callback
* we encountered a bug where % was getting set to 105, math.min fixes that
* @param num current progress in bytes
* @param size total file size in bytes
*/
setProgress(num: number, size: number) {
this.progress = Math.floor((num / size) * 100)
setProgress(num: number, size: number, name: string) {
this.$store.commit(
'ui/setFilesUploadStatus',
this.$t('pages.files.controls.upload', [
`${name} - ${Math.min(Math.floor((num / size) * 100), 100)}%`,
]),
)
},
},
})
Expand Down
2 changes: 2 additions & 0 deletions components/views/settings/pages/profile/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ export default Vue.extend({
const fileInput = this.$refs.file as HTMLInputElement
this.croppedImage = image
fileInput.value = ''
this.$store.dispatch('accounts/updateProfilePhoto', image)
},
/**
* @method selectProfileImage DocsTODO
Expand Down
12 changes: 8 additions & 4 deletions components/views/user/User.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export default Vue.extend({
?.lastUpdate ?? 0
)
},
textilePubkey: (state) =>
(state as RootState).accounts?.details?.textilePubkey || '',
}),
...mapGetters('textile', ['getConversation']),
lastMessage() {
Expand Down Expand Up @@ -172,23 +174,25 @@ export default Vue.extend({
}
},
getDescriptionFromMessage(message: Message) {
const sender = message.from === this.textilePubkey ? 'me' : 'user'
switch (message.type) {
case MessagingTypesEnum.TEXT:
return (message as TextMessage).payload
case MessagingTypesEnum.FILE:
return this.$t('messaging.user_sent', {
return this.$t(`messaging.user_sent.${sender}`, {
msgType: 'file',
})
case MessagingTypesEnum.GLYPH:
return this.$t('messaging.user_sent', {
return this.$t(`messaging.user_sent.${sender}`, {
msgType: 'glyph',
})
case MessagingTypesEnum.IMAGE:
return this.$t('messaging.user_sent_image', {
return this.$t(`messaging.user_sent_image.${sender}`, {
msgType: 'image',
})
default:
return this.$t('messaging.user_sent_something')
return this.$t(`messaging.user_sent_something.${sender}`)
}
},
},
Expand Down
4 changes: 2 additions & 2 deletions components/views/user/create/Create.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/>
<div v-if="showCropper" class="cropper-mask" />
<div class="modal-body">
<form v-on:submit="confirm">
<form @submit="confirm">
<div class="custom-modal-content">
<div class="columns">
<div class="column image">
Expand All @@ -23,7 +23,7 @@
class="input-file"
type="file"
@change="selectImage"
accept="image/*"
:accept="acceptableImageFormats"
/>
<InteractablesButton
:action="() => $refs.file.click()"
Expand Down
107 changes: 63 additions & 44 deletions components/views/user/create/Create.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
<template src="./Create.html"></template>

<script lang="ts">
import Vue, { PropType } from 'vue'
import { UserRegistrationData } from '~/types/ui/user'
import { isEmbeddableImage } from '~/utilities/FileType'
import Vue from 'vue'
import { isEmbeddableImage, isHeic } from '~/utilities/FileType'
import blobToBase64 from '~/utilities/BlobToBase64'
import { FILE_TYPE } from '~/libraries/Files/types/file'
import { PlatformTypeEnum } from '~/libraries/Enums/enums'
const convert = require('heic-convert')
export default Vue.extend({
name: 'CreateUser',
props: {
onConfirm: {
type: Function as PropType<(userData: UserRegistrationData) => void>,
required: true,
},
},
data() {
return {
showCropper: false,
Expand All @@ -37,6 +34,27 @@ export default Vue.extend({
}
return true
},
/**
* @method acceptableImageFormats
* @description embeddable types plus HEIC since we can convert
* ios doesn't support advanced <input> accept
* @returns {string} comma separated list of types
*/
acceptableImageFormats(): string {
return this.$envinfo.currentPlatform === PlatformTypeEnum.IOS
? 'image/*'
: [
FILE_TYPE.APNG,
FILE_TYPE.AVIF,
FILE_TYPE.GIF,
FILE_TYPE.JPG,
FILE_TYPE.PNG,
FILE_TYPE.WEBP,
FILE_TYPE.SVG,
FILE_TYPE.HEIC,
FILE_TYPE.HEIF,
].join(',')
},
},
methods: {
/**
Expand All @@ -54,65 +72,66 @@ export default Vue.extend({
* @example
*/
async selectImage(e: Event) {
this.error = ''
this.isLoading = true
const target = e.target as HTMLInputElement
if (target.value === null) {
// make sure there's file data available
if (target.value === null || !target.files?.length) {
this.isLoading = false
return
}
const files = target.files
// only one file allowed on this upload, this is an easier variable name to deal with
let file = target.files[0]
if (!files?.length) {
// stop upload if picture is too large for nsfw scan
if (file.size > this.$Config.nsfwPictureLimit) {
this.error = this.$t('errors.accounts.file_too_large') as string
this.isLoading = false
return
}
const isEmbeddable = await isEmbeddableImage(files[0])
if (!isEmbeddable) {
this.error = this.$t('errors.sign_in.invalid_file') as string
this.isLoading = false
return
// if heic, convert and then set file to png version
if (await isHeic(file)) {
const buffer = new Uint8Array(await file.arrayBuffer())
const oBuffer = await convert({
buffer,
format: 'PNG', // output format
quality: 1,
})
file = new File([oBuffer.buffer], 'profilePic.png', {
type: 'image/png',
})
}
// stop upload if picture is too large for nsfw scan
if (files[0].size > this.$Config.nsfwPictureLimit) {
this.error = this.$t('errors.accounts.file_too_large') as string
// if invalid file type, prevent upload. this needs to be added since safari mobile doesn't fully support <input> accept
if (!(await isEmbeddableImage(file))) {
this.error = this.$t('errors.accounts.invalid_file') as string
this.resetFileInput()
this.isLoading = false
return
}
// stop upload if picture is nsfw
// if nsfw, prevent upload
try {
const nsfw = await this.$Security.isNSFW(files[0])
if (nsfw) {
if (await this.$Security.isNSFW(file)) {
this.error = this.$t('errors.chat.contains_nsfw') as string
this.resetFileInput()
this.isLoading = false
return
}
} catch (err: any) {
this.$Logger.log('error', 'file upload error')
this.error = this.$t(err.message) as string
} catch (e: any) {
this.$Logger.log('error', 'file upload error', e)
this.error = this.$t('errors.accounts.invalid_file') as string
this.resetFileInput()
this.isLoading = false
return
}
this.error = ''
const reader = new FileReader()
reader.onload = (e) => {
if (e.target?.result) {
this.imageUrl = e.target.result.toString()
this.toggleCropper()
this.isLoading = false
}
}
reader.readAsDataURL(files[0])
this.imageUrl = await blobToBase64(file)
this.toggleCropper()
this.isLoading = false
},
/**
* @method resetFileInput
Expand All @@ -136,7 +155,6 @@ export default Vue.extend({
*/
setCroppedImage(image: string) {
this.croppedImage = image
this.resetFileInput()
},
/**
Expand All @@ -147,19 +165,20 @@ export default Vue.extend({
*/
confirm(e: Event) {
e.preventDefault()
if (this.isLoading) return false
if (this.isLoading) {
return false
}
if (!this.accountValidLength) {
this.error = this.$t('user.registration.username_error') as string
return false
}
this.error = ''
this.onConfirm({
this.$emit('confirm', {
username: this.name,
photoHash: this.croppedImage,
status: this.status,
})
return true
},
},
})
Expand Down
Loading

0 comments on commit 8c452b6

Please sign in to comment.