Skip to content

Commit

Permalink
Merge branch 'master' into feature/chelonia-in-service-worker
Browse files Browse the repository at this point in the history
  • Loading branch information
corrideat committed Nov 28, 2024
2 parents 24535cf + 4464fea commit 3e67bee
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 95 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ npm run cy:open
npx cypress run -c 'baseUrl=http://localhost:8000' --spec "test/cypress/integration/group-chat.spec.js"
```

This project is tested with BrowserStack. <!-- This string is necessary here for BrowserStack's free OSS testing. -->

#### Using Docker for extra security

You can run commands in a Docker container by using `npm run docker -- <cmd>` instead.
Expand Down
7 changes: 7 additions & 0 deletions frontend/assets/style/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@
}
}

$payment-table-desktop-bp: 1290px;
@mixin payment-table-desktop {
@media screen and (min-width: $payment-table-desktop-bp) {
@content;
}
}

%unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
Expand Down
20 changes: 13 additions & 7 deletions frontend/views/containers/chatroom/SendArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
:style='textareaStyles'
:maxlength='config.messageMaxChar'
@blur='textAreaBlur'
@keydown.enter.exact.prevent='handleKeyDownEnter'
@keydown.enter.exact='handleKeyDownEnter'
@keydown.tab.exact='handleKeyDownTab'
@keydown.ctrl='isNextLine'
@keydown='handleKeydown'
Expand Down Expand Up @@ -359,7 +359,8 @@ export default ({
messageMaxChar: CHATROOM_MAX_MESSAGE_LEN
},
typingUserTimeoutIds: {},
throttledEmitUserTypingEvent: throttle(this.emitUserTypingEvent, 500)
throttledEmitUserTypingEvent: throttle(this.emitUserTypingEvent, 500),
mediaIsPhone: null
}
},
watch: {
Expand All @@ -376,9 +377,9 @@ export default ({
},
created () {
// TODO #492 create a global Vue Responsive just for media queries.
const mediaIsPhone = window.matchMedia('(hover: none) and (pointer: coarse)')
this.ephemeral.isPhone = mediaIsPhone.matches
mediaIsPhone.onchange = (e) => { this.ephemeral.isPhone = e.matches }
this.mediaIsPhone = window.matchMedia('(hover: none) and (pointer: coarse)')
this.ephemeral.isPhone = this.mediaIsPhone.matches
this.mediaIsPhone.onchange = (e) => { this.ephemeral.isPhone = e.matches }
},
mounted () {
this.$refs.textarea.value = this.defaultText || ''
Expand All @@ -397,6 +398,7 @@ export default ({
sbp('okTurtles.events/off', CHATROOM_USER_TYPING, this.onUserTyping)
sbp('okTurtles.events/off', CHATROOM_USER_STOP_TYPING, this.onUserStopTyping)
this.mediaIsPhone.onchange = null // change handler needs to be destoryed to prevent memory leak.
this.ephemeral.staleObjectURLs.forEach(url => {
URL.revokeObjectURL(url)
})
Expand Down Expand Up @@ -531,12 +533,16 @@ export default ({
this.$refs.textarea.focus()
this.addSelectedMention(index)
},
handleKeyDownEnter () {
handleKeyDownEnter (e) {
const isNotPhone = !this.ephemeral.isPhone
if (this.ephemeral.mention.options.length) {
this.addSelectedMention(this.ephemeral.mention.index)
} else {
} else if (isNotPhone) {
this.sendMessage()
}
isNotPhone && e.preventDefault()
},
handleKeyDownTab (e) {
if (this.ephemeral.mention.options.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
v-if='objectURLList[entryIndex]'
:src='objectURLList[entryIndex]'
:alt='entry.name'
@click='openImageViewer(objectURLList[entryIndex], entry)'
@click='openImageViewer(objectURLList[entryIndex])'
)
.loading-box(v-else :style='loadingBoxStyles[entryIndex]')

Expand Down Expand Up @@ -60,7 +60,7 @@
v-for='(entry, entryIndex) in attachmentList'
:key='entryIndex'
:class='"is-" + fileType(entry)'
@click='openImageViewer(entry.url, entry)'
@click='openImageViewer(entry.url)'
)
img.c-preview-img(
v-if='fileType(entry) === "image" && entry.url'
Expand Down Expand Up @@ -94,6 +94,7 @@ import { MESSAGE_VARIANTS } from '@model/contracts/shared/constants.js'
import { getFileExtension, getFileType } from '@view-utils/filters.js'
import { Secret } from '~/shared/domains/chelonia/Secret.js'
import { OPEN_MODAL } from '@utils/events.js'
import { randomHexString } from '@model/contracts/shared/giLodash.js'
export default {
name: 'ChatAttachmentPreview',
Expand Down Expand Up @@ -212,21 +213,29 @@ export default {
height: `${heightInPixel}px`
}
},
openImageViewer (objectURL, data) {
if (objectURL) {
sbp(
'okTurtles.events/emit', OPEN_MODAL, 'ImageViewerModal',
null,
{
metaData: {
name: data.name,
ownerID: this.ownerID,
imgUrl: objectURL,
createdAt: this.createdAt || new Date()
}
openImageViewer (objectURL) {
if (!objectURL) { return }
const allImageAttachments = this.attachmentList.filter(entry => this.fileType(entry) === 'image')
.map((entry, index) => {
return {
name: entry.name,
ownerID: this.ownerID,
imgUrl: entry.url || this.objectURLList[index] || '',
createdAt: this.createdAt || new Date(),
id: randomHexString(12)
}
)
}
})
const initialIndex = allImageAttachments.findIndex(attachment => attachment.imgUrl === objectURL)
sbp(
'okTurtles.events/emit', OPEN_MODAL, 'ImageViewerModal',
null,
{
images: allImageAttachments,
initialIndex: initialIndex === -1 ? 0 : initialIndex
}
)
}
},
watch: {
Expand Down
149 changes: 119 additions & 30 deletions frontend/views/containers/chatroom/image-viewer/ImageViewerModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,43 @@
.c-image-viewer-modal(@wheel.prevent.stop='')
.c-image-viewer-content
.c-image-blurry-background(:style='blurryBgStyles')
preview-image-area(:img-src='metaData.imgUrl' :name='metaData.name')
preview-image-area(
v-if='currentImage'
:key='currentImage.id'
:img-src='currentImage.imgUrl'
:name='currentImage.name'
)

header.c-modal-header
avatar-user.c-avatar(
v-if='metaData.ownerID'
:contractID='metaData.ownerID'
v-if='currentImage.ownerID'
:contractID='currentImage.ownerID'
size='sm'
)

.c-img-data
.c-name.has-ellipsis {{ displayName }}
.c-filename.has-ellipsis {{ metaData.name }}
.c-filename.has-ellipsis {{ currentImage.name }}

button.is-icon-small.c-close-btn(
type='button'
@click.stop='close'
)
i.icon-times

button.is-icon.c-image-nav-btn.is-prev(
v-if='showPrevButton'
type='button'
@click='selectPrevImage'
)
i.icon-chevron-left

button.is-icon.c-image-nav-btn.is-next(
v-if='showNextButton'
type='button'
@click='selectNextImage'
)
i.icon-chevron-right
</template>

<script>
Expand All @@ -39,30 +58,19 @@ export default {
PreviewImageArea
},
props: {
metaData: Object
images: Array,
initialIndex: {
type: Number,
required: false,
default: 0
}
},
data () {
return {
testImgSrc: '/assets/images/home-bg.jpeg',
touchMatchMedia: null,
ephemeral: {
previewImgAttrs: {
width: undefined,
height: undefined
},
currentZoom: 0,
showSliderOutput: false
},
config: {
imgData: {
minWidth: null,
minHeight: null,
naturalWidth: null,
naturalHeight: null,
aspectRatio: 1 // intrinsic ratio value of width / height
},
zoomMin: 0,
zoomMax: 400, // for now.
sliderUnit: '%'
currentIndex: 0,
isTouch: false
}
}
},
Expand All @@ -73,36 +81,81 @@ export default {
]),
blurryBgStyles () {
return {
backgroundImage: `url(${this.metaData.imgUrl})`
backgroundImage: `url(${this.currentImage.imgUrl})`
}
},
displayName () {
const contractID = this.metaData.ownerID
const contractID = this.currentImage.ownerID
return this.globalProfile(contractID)?.displayName ||
this.usernameFromID(contractID)
},
hasMultipleImages () {
return Array.isArray(this.images) && this.images.length > 1
},
showPrevButton () {
const len = this.images.length
return len > 1 && this.ephemeral.currentIndex > 0
},
showNextButton () {
const len = this.images.length
return len > 1 && this.ephemeral.currentIndex < len - 1
},
currentImage () {
return this.images[this.ephemeral.currentIndex]
}
},
created () {
if (!this.metaData) {
if (!Array.isArray(this.images)) {
this.$nextTick(() => this.close())
} else {
this.ephemeral.currentIndex = this.initialIndex
}
this.touchMatchMedia = window.matchMedia('(hover: none) and (pointer: coarse)')
this.ephemeral.isTouch = this.touchMatchMedia.matches
this.touchMatchMedia.onchange = (e) => {
this.ephemeral.isTouch = e.matches
}
},
mounted () {
document.addEventListener('keydown', this.trapFocus)
document.addEventListener('keydown', this.keydownHandler)
},
beforeDestroy () {
document.removeEventListener('keydown', this.trapFocus)
document.removeEventListener('keydown', this.keydownHandler)
this.touchMatchMedia.onchange = null
},
methods: {
close () {
sbp('okTurtles.events/emit', CLOSE_MODAL, 'ImageViewerModal')
},
selectNextImage () {
if (this.ephemeral.currentIndex < this.images.length - 1) {
this.ephemeral.currentIndex += 1
}
},
selectPrevImage () {
if (this.ephemeral.currentIndex > 0) {
this.ephemeral.currentIndex -= 1
}
},
keydownHandler (e) {
this.trapFocus(e)
switch (e.key) {
case 'ArrowLeft':
this.selectPrevImage()
break
case 'ArrowRight':
this.selectNextImage()
}
}
}
}
</script>
<style lang="scss" scoped>
@import "@assets/style/_variables.scss";
$cta-zindex: 3;
.c-image-viewer-modal {
position: fixed;
Expand Down Expand Up @@ -140,6 +193,9 @@ export default {
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: row;
align-items: stretch;
@include from($tablet) {
border-radius: 0.375rem;
Expand All @@ -154,7 +210,7 @@ export default {
top: 0;
left: 0;
height: auto;
z-index: 3;
z-index: $cta-zindex;
padding: 1rem;
padding-right: 3rem;
display: flex;
Expand Down Expand Up @@ -230,4 +286,37 @@ export default {
color: var(--image-viewer-btn-text-color_active);
}
}
.c-image-nav-btn {
position: absolute;
z-index: $cta-zindex;
top: 50%;
transform: translateY(-50%);
background-color: var(--image-viewer-text-color);
color: var(--image-viewer-btn-color);
width: 2.5rem;
height: 2.5rem;
&.is-prev {
left: 1rem;
}
&.is-next {
right: 1rem;
}
@include phone {
width: 2rem;
height: 2rem;
font-size: 0.75rem;
&.is-prev {
left: 0.75rem;
}
&.is-next {
right: 0.75rem;
}
}
}
</style>
Loading

0 comments on commit 3e67bee

Please sign in to comment.