Skip to content

Commit

Permalink
svg mask v2
Browse files Browse the repository at this point in the history
  • Loading branch information
TinySmallM committed Feb 4, 2025
1 parent aa8e31f commit 80caa07
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 70 deletions.
3 changes: 0 additions & 3 deletions src/assets/icons/Icon32PauseCircle.svg

This file was deleted.

22 changes: 22 additions & 0 deletions src/assets/icons/Icon32PauseCircle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineComponent } from 'vue'
import { JSXElement } from 'misc/utils'

type Props = {
id: string
renderMask: () => JSXElement | undefined
insert?: JSXElement
}

export const Icon32PauseCircle = defineComponent<Props>((props) => {
const getRender = props.renderMask

return () => (
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<mask id={props.id}>{props.renderMask()}</mask>
<path mask={`url(#${props.id})`} d="M32 16a16 16 0 1 1-32 0 16 16 0 0 1 32 0zm-20.9-5.45c-.1.21-.1.49-.1 1.05v8.8c0 .56 0 .84.1 1.05a1 1 0 0 0 .45.44c.21.11.49.11 1.05.11h.8c.56 0 .84 0 1.05-.1a1 1 0 0 0 .44-.45c.11-.21.11-.49.11-1.05v-8.8c0-.56 0-.84-.1-1.05a1 1 0 0 0-.45-.44c-.21-.11-.49-.11-1.05-.11h-.8c-.56 0-.84 0-1.05.1a1 1 0 0 0-.44.45zm6 0c-.1.21-.1.49-.1 1.05v8.8c0 .56 0 .84.1 1.05a1 1 0 0 0 .45.44c.21.11.49.11 1.05.11h.8c.56 0 .84 0 1.05-.1a1 1 0 0 0 .44-.45c.11-.21.11-.49.11-1.05v-8.8c0-.56 0-.84-.1-1.05a1 1 0 0 0-.45-.44c-.21-.11-.49-.11-1.05-.11h-.8c-.56 0-.84 0-1.05.1a1 1 0 0 0-.44.45z" fill="currentColor" />
{getRender() && props.insert}
</svg>
)
}, {
props: ['renderMask', 'id', 'insert']
})
3 changes: 0 additions & 3 deletions src/assets/icons/Icon32PlayCircle.svg

This file was deleted.

22 changes: 22 additions & 0 deletions src/assets/icons/Icon32PlayCircle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineComponent } from 'vue'
import { JSXElement } from 'misc/utils'

type Props = {
id: string
renderMask: () => JSXElement | undefined
insert?: JSXElement
}

export const Icon32PlayCircle = defineComponent<Props>((props) => {
return () => (
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<mask id={props.id}>{props.renderMask()}</mask>
<g mask={`url(#${props.id})`}>
<path clip-rule="evenodd" d="M32 16c0 8.837-7.163 16-16 16S0 24.837 0 16 7.163 0 16 0s16 7.163 16 16zm-9.851.874a1.005 1.005 0 0 0 0-1.739l-8.644-4.994a1.003 1.003 0 0 0-1.505.87v9.988c0 .773.836 1.256 1.505.87z" fill="currentColor" fill-rule="evenodd" />
</g>
{props.renderMask() && props.insert}
</svg>
)
}, {
props: ['renderMask', 'id', 'insert']
})
6 changes: 4 additions & 2 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ export { default as Icon24ViewOutline } from './Icon24ViewOutline.svg'
export { default as Icon24VolumeOutline } from './Icon24VolumeOutline.svg'
export { default as Icon28DeleteOutline } from './Icon28DeleteOutline.svg'
export { default as Icon32DonutCircleFillYellow } from './Icon32DonutCircleFillYellow.svg'
// export { default as Icon32PauseCircle } from './Icon32PauseCircle.svg'
// export { default as Icon32PlayCircle } from './Icon32PlayCircle.svg'

export { Icon32PauseCircle } from './Icon32PauseCircle'
export { Icon32PlayCircle } from './Icon32PlayCircle'

export { default as Icon32Spinner } from './Icon32Spinner.svg'
export { default as Icon44Spinner } from './Icon44Spinner.svg'
3 changes: 3 additions & 0 deletions src/converters/MessageConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export function fromApiMessage(message: MessagesMessage): Message.Message {
return {
kind: 'Normal',
text: message.text,
wasListened: message.was_listened ?? false,
attaches: fromApiAttaches(message.attachments ?? []),
replyMessage: message.reply_message && fromApiForeignMessage(
message.reply_message,
Expand Down Expand Up @@ -164,6 +165,7 @@ function fromApiForeignMessage(
authorId: Peer.resolveOwnerId(foreignMessage.from_id),
sentAt: foreignMessage.date * 1000,
text: foreignMessage.text,
wasListened: false,
attaches: fromApiAttaches(foreignMessage.attachments ?? []),
replyMessage: foreignMessage.reply_message && fromApiForeignMessage(
foreignMessage.reply_message,
Expand Down Expand Up @@ -211,6 +213,7 @@ export function fromApiPinnedMessage(pinnedMessage: MessagesPinnedMessage): Mess
authorId: Peer.resolveOwnerId(pinnedMessage.from_id),
sentAt: pinnedMessage.date * 1000,
text: pinnedMessage.text,
wasListened: false,
attaches: fromApiAttaches(pinnedMessage.attachments ?? []),
replyMessage: pinnedMessage.reply_message && fromApiForeignMessage(
pinnedMessage.reply_message,
Expand Down
1 change: 1 addition & 0 deletions src/model/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface Normal extends BaseMessage {
kind: 'Normal'
text: string
attaches: Attach.Attaches
wasListened: boolean
replyMessage?: Foreign
forwardedMessages?: NonEmptyArray<Foreign>
}
Expand Down
8 changes: 7 additions & 1 deletion src/ui/messenger/ConvoMessage/ConvoMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ export const ConvoMessage = defineComponent<Props>((props) => {
)}

{message.text && <span class="ConvoMessage__text">{message.text}</span>}
{hasAttaches && <Attaches class="ConvoMessage__attaches" attaches={message.attaches} />}
{hasAttaches && (
<Attaches
class="ConvoMessage__attaches"
attaches={message.attaches}
isWasListened={message.wasListened}
/>
)}

{isEmpty && (
<span class="ConvoMessage__empty">
Expand Down
35 changes: 0 additions & 35 deletions src/ui/messenger/MessagerController/MessagerController.tsx

This file was deleted.

80 changes: 56 additions & 24 deletions src/ui/messenger/attaches/AttachVoice/AttachVoice.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { computed, defineComponent, InputEvent, shallowRef } from 'vue'
import * as Attach from 'model/Attach'
import { useEnv } from 'hooks'
import { MessagerController } from 'ui/messenger/MessagerController/MessagerController'
import { ButtonIcon } from 'ui/ui/ButtonIcon/ButtonIcon'
import { Icon16Text, Icon20ChevronUp } from 'assets/icons'
import { Icon16Text, Icon20ChevronUp, Icon32PauseCircle, Icon32PlayCircle } from 'assets/icons'
import './AttachVoice.css'

type Props = {
voice: Attach.Voice
isWasListened?: boolean
}

export const AttachVoice = defineComponent<Props>((props) => {
Expand All @@ -20,6 +20,8 @@ export const AttachVoice = defineComponent<Props>((props) => {
const requestId = shallowRef(-1)
const isHiddenCollapse = shallowRef(true)

console.log(props.isWasListened, props.voice.transcript)

const transcriptNotReady = computed(() => {
return !props.voice.transcript ||
props.voice.transcript.trim() === '' ||
Expand All @@ -28,7 +30,7 @@ export const AttachVoice = defineComponent<Props>((props) => {
})

const text = computed(() => {
if (props.voice.transcript && props.voice.transcript.trim() === '') {
if (!props.voice.transcript || props.voice.transcript.trim() === '') {
return lang.use('me_voice_transcription_empty')
}

Expand All @@ -43,6 +45,19 @@ export const AttachVoice = defineComponent<Props>((props) => {
return props.voice.transcript
})

const getCircleMask = () => {
if (props.isWasListened) {
return
}

return (
<>
<rect width="100%" height="100%" fill="white" />
<circle cx="27" cy="27" r="5" />
</>
)
}

const getCurrentTime = () => {
const currentTime = audio.currentTime === 0
? props.voice.duration
Expand Down Expand Up @@ -92,28 +107,44 @@ export const AttachVoice = defineComponent<Props>((props) => {
<div class="AttachVoice__player">
<ButtonIcon
onClick={toggleAudio}
icon={
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<mask id="circle">
<rect width="100%" height="100%" // fill="white" - упрввление цветом, расскоментируй Дань!
/>
<circle cx="27" cy="27" r="5" />
</mask>
<g mask="url(#circle)">
<path clip-rule="evenodd" d="M32 16c0 8.837-7.163 16-16 16S0 24.837 0 16 7.163 0 16 0s16 7.163 16 16zm-9.851.874a1.005 1.005 0 0 0 0-1.739l-8.644-4.994a1.003 1.003 0 0 0-1.505.87v9.988c0 .773.836 1.256 1.505.87z" fill="currentColor" fill-rule="evenodd"/>
</g>
<circle cx="27" cy="27" r="3" fill="currentColor" />
</svg>
}
icon={isPause.value
? (
<Icon32PauseCircle
id="circle"
renderMask={getCircleMask}
insert={<circle cx="27" cy="27" r="3" fill="currentColor" />}
/>
)
: (
<Icon32PlayCircle
id="circle"
renderMask={getCircleMask}
insert={<circle cx="27" cy="27" r="3" fill="currentColor" />}
/>
)}
/>
{/* <MessagerController /> //Чтоб линтер не ругался */}
<MessagerController id="pause" />
{/* //Появляется на пару сек и пропадает. Но в dom изменений нет */}
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<mask id="circle">
<rect
width="100%"
height="100%"
fill="white"
/>
<circle cx="27" cy="27" r="5" />
</mask>
<g mask="url(#circle)">
<path clip-rule="evenodd" d="M32 16c0 8.837-7.163 16-16 16S0 24.837 0 16 7.163 0 16 0s16 7.163 16 16zm-9.851.874a1.005 1.005 0 0 0 0-1.739l-8.644-4.994a1.003 1.003 0 0 0-1.505.87v9.988c0 .773.836 1.256 1.505.87z" fill="currentColor" fill-rule="evenodd" />
</g>
<circle cx="27" cy="27" r="3" fill="currentColor" />
</svg>

<div class="AttachVoice__track">
<div class="AttachVoice__trackContent">
<input
class="AttachVoice__range"
type="range"
step="0.1"
id="track"
name="track"
value={range.value}
Expand All @@ -136,11 +167,12 @@ export const AttachVoice = defineComponent<Props>((props) => {
</div>
{!isHiddenCollapse.value && (
<div class="AttachVoice__transcript">
<div class={['AttachVoice__collapse', {
'AttachVoice__collapse--open': !isHiddenCollapse.value,
'AttachVoice__collapse--close': isHiddenCollapse.value,
'AttachVoice__collapse--faded': transcriptNotReady.value
}]}
<div
class={['AttachVoice__collapse', {
'AttachVoice__collapse--open': !isHiddenCollapse.value,
'AttachVoice__collapse--close': isHiddenCollapse.value,
'AttachVoice__collapse--faded': transcriptNotReady.value
}]}
>
{text.value}
</div>
Expand All @@ -149,5 +181,5 @@ export const AttachVoice = defineComponent<Props>((props) => {
</div>
)
}, {
props: ['voice']
props: ['voice', 'isWasListened']
})
7 changes: 5 additions & 2 deletions src/ui/messenger/attaches/Attaches.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import './Attaches.css'

type Props = {
attaches: Attach.Attaches
isWasListened?: boolean
class: ClassName
}

Expand All @@ -23,7 +24,9 @@ export const Attaches = defineComponent<Props>((props) => {
{props.attaches.photos && <AttachPhotos photos={props.attaches.photos} />}
{props.attaches.links?.map((link) => <AttachLink link={link} />)}
{props.attaches.wall && <AttachWall wall={props.attaches.wall} />}
{props.attaches.voice && <AttachVoice voice={props.attaches.voice} />}
{props.attaches.voice && (
<AttachVoice voice={props.attaches.voice} isWasListened={props.isWasListened} />
)}
{props.attaches.unknown?.map((unknown) => (
<div class="Attaches__unknown">
{lang.use('me_unknown_attach')} ({unknown.type})
Expand All @@ -32,5 +35,5 @@ export const Attaches = defineComponent<Props>((props) => {
</div>
)
}, {
props: ['attaches', 'class']
props: ['attaches', 'class', 'isWasListened']
})
1 change: 1 addition & 0 deletions src/ui/ui/ButtonIcon/ButtonIcon.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
flex: none;
position: relative;
border-radius: 6px;
line-height: 0;
transition: background-color var(--fastTransition), opacity var(--fastTransition);
}

Expand Down
Binary file added vk.zip
Binary file not shown.

0 comments on commit 80caa07

Please sign in to comment.