Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(userStatus): migrate util to Typescript #13111

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/__mocks__/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Capabilities } from '../types'
import type { Capabilities } from '../types/index.ts'

export const mockedCapabilities: Capabilities = {
spreed: {
Expand Down
7 changes: 6 additions & 1 deletion src/components/BreakoutRoomsEditor/SelectableParticipant.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
:source="participant.source || participant.actorType"
disable-menu
disable-tooltip
:preloaded-user-status="preloadedUserStatus"
Antreesy marked this conversation as resolved.
Show resolved Hide resolved
show-user-status />

<span class="selectable-participant__content">
Expand All @@ -36,7 +37,7 @@ import IconCheck from 'vue-material-design-icons/Check.vue'

import AvatarWrapper from '../AvatarWrapper/AvatarWrapper.vue'

import { getStatusMessage } from '../../utils/userStatus.js'
import { getPreloadedUserStatus, getStatusMessage } from '../../utils/userStatus.ts'

export default {
name: 'SelectableParticipant',
Expand Down Expand Up @@ -73,6 +74,10 @@ export default {
},
},

preloadedUserStatus() {
return getPreloadedUserStatus(this.participant)
},

participantStatus() {
return getStatusMessage(this.participant)
},
Expand Down
13 changes: 5 additions & 8 deletions src/components/ConversationIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import { useIsDarkTheme } from '../composables/useIsDarkTheme.ts'
import { AVATAR, CONVERSATION } from '../constants.js'
import { getConversationAvatarOcsUrl } from '../services/avatarService.ts'
import { hasTalkFeature } from '../services/CapabilitiesManager.ts'
import { getPreloadedUserStatus } from '../utils/userStatus.ts'

const supportsAvatar = hasTalkFeature('local', 'avatar')

Expand Down Expand Up @@ -151,15 +152,11 @@ export default {
},

preloadedUserStatus() {
if (!this.hideUserStatus && Object.prototype.hasOwnProperty.call(this.item, 'statusMessage')) {
// We preloaded the status
return {
status: this.item.status || null,
message: this.item.statusMessage || null,
icon: this.item.statusIcon || null,
}
if (this.hideUserStatus) {
return undefined
}
return undefined

return getPreloadedUserStatus(this.item)
},

menuContainer() {
Expand Down
20 changes: 2 additions & 18 deletions src/components/RightSidebar/Participants/Participant.vue
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ import {
import { hasTalkFeature } from '../../../services/CapabilitiesManager.ts'
import { formattedTime } from '../../../utils/formattedTime.ts'
import { readableNumber } from '../../../utils/readableNumber.ts'
import { getStatusMessage } from '../../../utils/userStatus.js'
import { getPreloadedUserStatus, getStatusMessage } from '../../../utils/userStatus.ts'

export default {
name: 'Participant',
Expand Down Expand Up @@ -826,23 +826,7 @@ export default {
},

preloadedUserStatus() {
if (Object.prototype.hasOwnProperty.call(this.participant, 'statusMessage')) {
// We preloaded the status when via participants API
return {
status: this.participant.status || null,
message: this.participant.statusMessage || null,
icon: this.participant.statusIcon || null,
}
}
if (Object.prototype.hasOwnProperty.call(this.participant, 'status')) {
// We preloaded the status when via search API
return {
status: this.participant.status.status || null,
message: this.participant.status.message || null,
icon: this.participant.status.icon || null,
}
}
return undefined
return getPreloadedUserStatus(this.participant)
},

attendeePermissions() {
Expand Down
2 changes: 1 addition & 1 deletion src/components/TopBar/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ import { AVATAR, CONVERSATION } from '../../constants.js'
import BrowserStorage from '../../services/BrowserStorage.js'
import { getTalkConfig } from '../../services/CapabilitiesManager.ts'
import { useChatExtrasStore } from '../../stores/chatExtras.js'
import { getStatusMessage } from '../../utils/userStatus.js'
import { getStatusMessage } from '../../utils/userStatus.ts'
import { localCallParticipantModel, localMediaModel } from '../../utils/webrtc/index.js'

export default {
Expand Down
2 changes: 1 addition & 1 deletion src/composables/useSortParticipants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { computed } from 'vue'

import { useStore } from './useStore.js'
import { ATTENDEE, PARTICIPANT } from '../constants.js'
import { isDoNotDisturb } from '../utils/userStatus.js'
import { isDoNotDisturb } from '../utils/userStatus.ts'

const MODERATOR_TYPES = [PARTICIPANT.TYPE.OWNER, PARTICIPANT.TYPE.MODERATOR, PARTICIPANT.TYPE.GUEST_MODERATOR]

Expand Down
2 changes: 1 addition & 1 deletion src/services/CapabilitiesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { t } from '@nextcloud/l10n'
import { getRemoteCapabilities } from './federationService.ts'
import BrowserStorage from '../services/BrowserStorage.js'
import { useTalkHashStore } from '../stores/talkHash.js'
import type { Capabilities, Conversation, JoinRoomFullResponse } from '../types'
import type { Capabilities, Conversation, JoinRoomFullResponse } from '../types/index.ts'

type Config = Capabilities['spreed']['config']
type RemoteCapability = Capabilities & Partial<{ hash: string }>
Expand Down
4 changes: 2 additions & 2 deletions src/services/avatarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import type {
deleteAvatarResponse,
setEmojiAvatarParams,
setEmojiAvatarResponse,
setFileAvatarResponse
} from '../types'
setFileAvatarResponse,
} from '../types/index.ts'

const getConversationAvatarOcsUrl = function(token: string, isDarkTheme: boolean, avatarVersion?: string): string {
return generateOcsUrl('apps/spreed/api/v1/room/{token}/avatar' + (isDarkTheme ? '/dark' : '') + (avatarVersion ? '?v={avatarVersion}' : ''), { token, avatarVersion })
Expand Down
2 changes: 1 addition & 1 deletion src/services/banService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {
banActorParams,
banActorResponse,
unbanActorResponse,
} from '../types'
} from '../types/index.ts'

/**
* Get information about configured bans for this conversation
Expand Down
2 changes: 1 addition & 1 deletion src/services/botsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'

import type { Bot, getBotsResponse, getBotsAdminResponse, enableBotResponse, disableBotResponse } from '../types'
import type { Bot, getBotsResponse, getBotsAdminResponse, enableBotResponse, disableBotResponse } from '../types/index.ts'

/**
* Get information about available bots for this instance
Expand Down
2 changes: 1 addition & 1 deletion src/services/breakoutRoomsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
stopBreakoutRoomsResponse,
switchToBreakoutRoomParams,
switchToBreakoutRoomResponse,
} from '../types'
} from '../types/index.ts'

/**
* Create breakout rooms for a given conversation
Expand Down
2 changes: 1 addition & 1 deletion src/services/federationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'

import type { acceptShareResponse, getSharesResponse, rejectShareResponse, getCapabilitiesResponse } from '../types'
import type { acceptShareResponse, getSharesResponse, rejectShareResponse, getCapabilitiesResponse } from '../types/index.ts'

/**
* Fetches list of shares for a current user
Expand Down
4 changes: 2 additions & 2 deletions src/services/messagesService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import type {
receiveMessagesParams,
receiveMessagesResponse,
setReadMarkerParams,
setReadMarkerResponse
} from '../types'
setReadMarkerResponse,
} from '../types/index.ts'

type ReceiveMessagesPayload = Partial<receiveMessagesParams> & { token: string }
type GetMessageContextPayload = getMessageContextParams & { token: string, messageId: number }
Expand Down
4 changes: 2 additions & 2 deletions src/services/reactionsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import type {
addReactionResponse,
deleteReactionParams,
deleteReactionResponse,
getReactionsResponse
} from '../types'
getReactionsResponse,
} from '../types/index.ts'

const addReactionToMessage = async function(token: string, messageId: number, selectedEmoji: addReactionParams['reaction'], options: object): addReactionResponse {
return axios.post(generateOcsUrl('apps/spreed/api/v1/reaction/{token}/{messageId}', {
Expand Down
2 changes: 1 addition & 1 deletion src/stores/bots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Vue from 'vue'

import { BOT } from '../constants.js'
import { disableBotForConversation, enableBotForConversation, getConversationBots } from '../services/botsService.ts'
import type { Bot } from '../types'
import type { Bot } from '../types/index.ts'

type State = {
bots: Record<string, Record<number, Bot>>
Expand Down
4 changes: 2 additions & 2 deletions src/stores/breakoutRooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import type {
broadcastChatMessageParams,
configureBreakoutRoomsParams,
reorganizeAttendeesParams,
switchToBreakoutRoomParams
} from '../types'
switchToBreakoutRoomParams,
} from '../types/index.ts'

type Payload<T> = T & { token: string }
type State = {
Expand Down
2 changes: 1 addition & 1 deletion src/stores/federation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getBaseUrl } from '@nextcloud/router'

import { FEDERATION } from '../constants.js'
import { getShares, acceptShare, rejectShare } from '../services/federationService.ts'
import type { Conversation, FederationInvite, NotificationInvite } from '../types'
import type { Conversation, FederationInvite, NotificationInvite } from '../types/index.ts'

type State = {
pendingShares: Record<string, FederationInvite & { loading?: 'accept' | 'reject' }>,
Expand Down
15 changes: 15 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,22 @@ export type JoinRoomFullResponse = {
}

// Participants
export type ParticipantStatus = {
status?: string | null,
message?: string | null,
icon?: string | null,
clearAt?: number | null,
}
export type Participant = components['schemas']['Participant']
export type ParticipantSearchResult = {
id: string,
label: string,
icon: string,
source: string,
subline: string,
shareWithDisplayNameUnique: string,
status: ParticipantStatus | '',
}

// Chats
export type Mention = RichObject<'server'|'call-type'|'icon-url'>
Expand Down
2 changes: 1 addition & 1 deletion src/utils/getItemTypeFromMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { SHARED_ITEM } from '../constants.js'
import type { ChatMessage } from '../types'
import type { ChatMessage } from '../types/index.ts'

export const getItemTypeFromMessage = function(message: ChatMessage): string {
if (message.messageParameters?.object) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/textParse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { getBaseUrl } from '@nextcloud/router'

import type { ChatMessage, Mention } from '../types'
import type { ChatMessage, Mention } from '../types/index.ts'

/**
* Parse message text to return proper formatting for mentions
Expand Down
43 changes: 0 additions & 43 deletions src/utils/userStatus.js

This file was deleted.

80 changes: 80 additions & 0 deletions src/utils/userStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { t } from '@nextcloud/l10n'

import type {
Conversation,
Participant,
ParticipantSearchResult,
ParticipantStatus,
} from '../types/index.ts'

/**
* Generate user status object to use as preloaded status with NcAvatar
*
* @param userData user data (from conversation, participant, search result)
*/
export function getPreloadedUserStatus(userData?: Conversation | Participant | ParticipantSearchResult): ParticipantStatus | undefined {
if (!userData || typeof userData !== 'object') {
return undefined
}

if ('statusMessage' in userData) {
// We preloaded the status when via participants API
return {
status: userData.status || null,
message: userData.statusMessage || null,
icon: userData.statusIcon || null,
}
}
if ('status' in userData && typeof userData.status === 'object') {
// We preloaded the status when via search API
return {
status: userData.status.status || null,
message: userData.status.message || null,
icon: userData.status.icon || null,
}
}
return undefined
}

/**
* Generate full status message for user according to its status data
*
* @param userData user data
*/
export function getStatusMessage(userData?: Conversation | Participant | ParticipantSearchResult | ''): string {
if (!userData) {
return ''
}

const userStatus = getPreloadedUserStatus(userData)

if (!userStatus) {
return ''
}

let status = userStatus.icon ?? ''

if (userStatus.message) {
status += ' ' + userStatus.message
} else if (userStatus.status === 'dnd') {
status += ' ' + t('spreed', 'Do not disturb')
} else if (userStatus.status === 'away') {
status += ' ' + t('spreed', 'Away')
}

return status
}

/**
* Check if current status is "Do not disturb"
*
* @param userData user data
*/
export function isDoNotDisturb(userData: Conversation | Participant | ParticipantSearchResult): boolean {
return userData?.status === 'dnd'
}
Loading