Skip to content

Commit

Permalink
Merge branch 'master' into 2455-implement-push-notifications-for-noti…
Browse files Browse the repository at this point in the history
…fications-in-templatesjs
  • Loading branch information
corrideat committed Dec 31, 2024
2 parents 0ddaaa4 + 160bb62 commit 1981a2f
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 67 deletions.
4 changes: 4 additions & 0 deletions frontend/assets/style/components/_custom-markdowns.scss
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,8 @@
font-size: 0.7rem;
color: var(--text_1);
}

.chat-emoji {
font-size: 1.2em;
}
}
170 changes: 132 additions & 38 deletions frontend/views/components/Tooltip.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
<template lang='pug'>
span.c-twrapper(
:class='{ "has-target-within": triggerElementSelector }'
:class='{ "has-target-within": triggerElementSelector, "anchored-to-element": anchorToElement }'
v-bind='rootElAttrs'
)
slot

transition(name='fade')
.c-background(
v-if='(isActive || isVisible) && manual'
@click='toggle'
v-append-to-body=''
data-test='closeProfileCard'
template(v-if='revealTooltip')
.c-anchored-tooltip(
v-if='anchorToElement'
:class='tooltipClasses'
:style='styles'
v-anchor-to-trigger=''
)
// Default tooltip is text
template(v-if='text') {{text}}
// But any content can fit in
slot(v-else='' name='tooltip')

.c-tooltip(
:style='styles'
:class='{"has-text-center": isTextCenter, "is-active": isActive, manual, "is-dark-theme": $store.getters.isDarkTheme, "in-reduced-motion": isReducedMotionMode }'
v-if='isActive || isVisible'
v-append-to-body='{ manual }'
)
// Default tooltip is text
template(v-if='text') {{text}}
// But any content can fit in
slot(v-else='' name='tooltip')
template(v-else)
transition(name='fade')
.c-background(
v-if='manual'
@click='toggle'
v-append-to-body=''
data-test='closeProfileCard'
)

.c-tooltip(
:style='styles'
:class='tooltipClasses'
v-append-to-body='{ manual }'
)
// Default tooltip is text
template(v-if='text') {{text}}
// But any content can fit in
slot(v-else='' name='tooltip')
</template>

<script>
Expand All @@ -38,6 +50,8 @@ export default ({
// Force to show tooltip manually
isVisible: Boolean,
manual: {
// The option to opt out of the default behaviour of displaying tooltip when the trigger element is focused/hovered
// and then using $ref.[name].toggle() from the parent component instead. (reference: ProfileCard.vue)
type: Boolean,
default: false
},
Expand Down Expand Up @@ -67,6 +81,13 @@ export default ({
type: String,
required: false,
default: ''
},
anchorToElement: {
// An option to opt out of the v-append-to-body vue-directive. Instead of appending the tooltip to document.body,
// It will be anchored to the trigger DOM element so it won't detached from the original position while scrolling the page etc..
// (reference: https://github.com/okTurtles/group-income/issues/2450)
type: Boolean,
default: false
}
},
data: () => ({
Expand All @@ -81,7 +102,8 @@ export default ({
}),
computed: {
...mapGetters([
'isReducedMotionMode'
'isReducedMotionMode',
'isDarkTheme'
]),
rootElAttrs () {
return {
Expand All @@ -90,6 +112,18 @@ export default ({
: null,
'aria-label': !this.triggerElementSelector ? this.text : undefined
}
},
revealTooltip () {
return this.isActive || this.isVisible
},
tooltipClasses () {
return {
'has-text-center': this.isTextCenter,
'is-active': this.isActive,
'is-dark-theme': this.isDarkTheme,
'in-reduced-motion': this.isReducedMotionMode,
manual: this.manual
}
}
},
methods: {
Expand All @@ -99,12 +133,9 @@ export default ({
hide () {
if (!this.manual) this.isActive = false
},
// Used by parent (ProfileCard.vue)
toggle () {
if (this.deactivated) {
return
}
if (!this.manual) { return false }
// Manually toggle on/off the tooltip (reference: ProfileCard.vue)
if (this.deactivated || !this.manual) { return }
this.isActive = !this.isActive
},
handleKeyUp (e) {
Expand All @@ -115,17 +146,63 @@ export default ({
},
adjustPosition () {
this.trigger = (this.triggerDOM || this.$el).getBoundingClientRect()
const { scrollX, scrollY } = window
const { width, height, left, top } = this.trigger
const windowHeight = window.innerHeight
const spacing = 16
let x, y
let transform
let absPosition // For css top/left/bottom/right properties to use along with 'position: absolute'
if (this.manual && window.innerWidth < TABLET) {
y = windowHeight - this.tooltipHeight // Position at the bottom of the screen on mobile
x = -8 // Remove tooltip padding
// On mobile, position tooltip at the bottom of the screen with the side-padding removed.
transform = `translate(-8px, ${windowHeight - this.tooltipHeight}px)`
} else if (this.anchorToElement) {
let x, y // for css transform: translate(...)
switch (this.direction) {
case 'right':
x = '100%'
y = '-50%'
absPosition = { top: '50%', right: `-${spacing}px` }
break
case 'left':
x = '-100%'
y = '-50%'
absPosition = { top: '50%', left: `-${spacing}px` }
break
case 'bottom-left':
x = 0
y = '100%'
absPosition = { bottom: `-${spacing}px` }
break
case 'bottom-right':
x = 0
y = '100%'
absPosition = { bottom: `-${spacing}px`, right: 0 }
break
case 'top':
x = '-50%'
y = '-100%'
absPosition = { top: `-${spacing}px`, left: '50%' }
break
case 'top-left':
x = 0
y = '-100%'
absPosition = { top: `-${spacing}px`, left: 0 }
break
default: // defaults to 'bottom'
x = '-50%'
y = '100%'
absPosition = { left: '50%', bottom: `-${spacing}px` }
}
transform = `translate(${x}, ${y})`
} else {
y = scrollY + top + height / 2 - this.tooltipHeight / 2
let x
let y = scrollY + top + height / 2 - this.tooltipHeight / 2 // y position defaults to the trigger's center.
// If y position is off-screen, move it to the edges with some spacing.
if (y < 0) y = spacing
if (y + this.tooltipHeight > windowHeight) y = windowHeight - spacing - this.tooltipHeight
Expand Down Expand Up @@ -156,19 +233,22 @@ export default ({
x = scrollX + left + width / 2 - this.tooltipWidth / 2
y = scrollY + top + height + spacing
}
transform = `translate(${x}px, ${y}px)`
}
this.styles = {
transform: `translate(${x}px, ${y}px)`,
transform,
...(absPosition || {}),
pointerEvents: this.manual ? 'initial' : 'none',
backgroundColor: this.manual ? 'transparent' : 'var(--text_0)',
backgroundColor: this.manual ? 'transparent' : undefined,
opacity: this.opacity
}
}
},
directives: {
// The tooltip instead of being rendered on the original DOM position
// it's appended to the DOM, away from every other elements
// it's appended to the 'div.l-page' page element, away from every other elements
// so no element CSS can influence tooltip styles (position, size)
appendToBody: {
inserted (el, bindings, vnode) {
Expand Down Expand Up @@ -220,6 +300,17 @@ export default ({
}
window.removeEventListener('resize', $this.adjustPosition)
}
},
anchorToTrigger: {
inserted (el, bindings, vnode) {
const $this = vnode.context
if ($this.triggerElementSelector) {
// Append the tooltip to a particular element (which is specified by a selector)
$this.triggerDOM.appendChild(el)
}
$this.adjustPosition()
}
}
},
mounted () {
Expand Down Expand Up @@ -248,11 +339,18 @@ export default ({
<style lang="scss" scoped>
@import "@assets/style/_variables.scss";
.c-twrapper:not(.has-target-within) {
cursor: pointer;
.c-twrapper {
&.anchored-to-element {
position: relative;
}
&:not(.has-target-within) {
cursor: pointer;
}
}
.c-tooltip {
.c-tooltip,
.c-anchored-tooltip {
position: absolute;
top: 0;
left: 0;
Expand All @@ -274,12 +372,8 @@ export default ({
max-width: unset;
}
&.is-dark-theme {
&.is-dark-theme .card {
background-color: $general_1;
.card {
background-color: $general_1;
}
}
&.in-reduced-motion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,17 @@ export default ({
},
generateTextObjectsFromText (text) {
const containsMentionChar = str => new RegExp(`[${CHATROOM_MEMBER_MENTION_SPECIAL_CHAR}${CHATROOM_CHANNEL_MENTION_SPECIAL_CHAR}]`, 'g').test(text)
const wrapEmojis = str => {
// We should be able to style the emojis in message-text (reference issue: https://github.com/okTurtles/group-income/issues/2464)
return str.replace(/(\p{Emoji})/gu, '<span class="chat-emoji">$1</span>')
}
if (!text) { return [] }
if (!containsMentionChar(text)) {
return [{ type: TextObjectType.Text, text }]
return [{
type: TextObjectType.Text,
text: wrapEmojis(text)
}]
}
const allMention = makeMentionFromUserID('').all
const regExpPossibleMentions = new RegExp(`(?<=\\s|^)(${allMention}|${this.possibleMentions.join('|')})(?=[^\\w\\d]|$)`)
Expand All @@ -105,7 +112,8 @@ export default ({
.split(regExpPossibleMentions)
.map(t => {
const genDefaultTextObj = (text) => ({
type: TextObjectType.Text, text
type: TextObjectType.Text,
text: wrapEmojis(text)
})
const genChannelMentionObj = (text) => {
const chatRoomID = getIdFromChannelMention(text)
Expand Down Expand Up @@ -183,25 +191,27 @@ export default ({
background-color: $warning_1;
}
.c-message-text.is-replying {
border-left: 2px;
border-color: #dbdbdb; // var(--text_1);
border-style: none none none solid;
font-size: 0.75rem;
color: var(--text_1);
font-style: italic;
padding-left: 0.25rem;
white-space: pre-line;
&:hover {
cursor: pointer;
color: var(--text_2);
border-color: var(--text_1); // var(--text_2);
}
.c-message-text {
&.is-replying {
border-left: 2px;
border-color: #dbdbdb; // var(--text_1);
border-style: none none none solid;
font-size: 0.75rem;
color: var(--text_1);
font-style: italic;
padding-left: 0.25rem;
white-space: pre-line;
&:hover {
cursor: pointer;
color: var(--text_2);
border-color: var(--text_1); // var(--text_2);
}
.c-member-mention,
.c-channel-mention {
background-color: transparent;
.c-member-mention,
.c-channel-mention {
background-color: transparent;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ component(
:key='members.length'
:opacity='members.length === 0 ? 0 : 0.95'
triggerElementSelector='.t-trigger'
direction='bottom'
direction='bottom-left'
:anchorToElement='true'
)
// The reason for using <component /> tag here instead of <tooltip /> and specifying 'key' attr is,
// to fix the bug where the link between the tooltip content(template(slot='tooltip') below) and the trigger target element(.t-trigger)
Expand Down Expand Up @@ -34,15 +35,12 @@ export default ({
</script>

<style lang="scss" scoped>
.has-zero-members ::v-deep .c-tooltip {
display: none !important;
}
.c-member-name {
// Turn the parent element into flex-box to render ellipsis style properly.
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
font-weight: normal;
}
</style>
Loading

0 comments on commit 1981a2f

Please sign in to comment.