Skip to content
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 lib/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Config {
/**
* 1. Call recording, …
*/
public const FEATURE_HINT = 1;
public const FEATURE_HINT = 34;

/**
* Currently limiting to 1k users because the user_status API would yield
Expand Down
60 changes: 58 additions & 2 deletions src/components/CallView/BottomBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ import {
} from '../../composables/useDocumentFullscreen.ts'
import { useGetToken } from '../../composables/useGetToken.ts'
import { CONVERSATION, PARTICIPANT } from '../../constants.ts'
import { getTalkConfig } from '../../services/CapabilitiesManager.ts'
import {
getTalkConfig,
showTalkFeatureHint,
} from '../../services/CapabilitiesManager.ts'
import { useActorStore } from '../../stores/actor.ts'
import { useBreakoutRoomsStore } from '../../stores/breakoutRooms.ts'
import { useCallViewStore } from '../../stores/callView.ts'
Expand Down Expand Up @@ -77,7 +80,9 @@ const canModerate = computed(() => [PARTICIPANT.TYPE.OWNER, PARTICIPANT.TYPE.MOD
.includes(conversation.value.participantType))

const isLiveTranscriptionSupported = computed(() => getTalkConfig(token.value, 'call', 'live-transcription') || false)
const hintTranscriptionSupported = computed(() => !isLiveTranscriptionSupported.value && showTalkFeatureHint(34))
const isLiveTranslationSupported = computed(() => getTalkConfig(token.value, 'call', 'live-translation') || false)
const hintTranslationSupported = computed(() => !isLiveTranslationSupported.value && showTalkFeatureHint(34))

const liveTranscriptionButtonLabel = computed(() => {
if (callViewStore.isLiveTranscriptionEnabled && languageType.value === LanguageType.Original) {
Expand All @@ -87,6 +92,10 @@ const liveTranscriptionButtonLabel = computed(() => {
return t('spreed', 'Enable live transcription (generated by AI)')
})

const hintTranscriptionButtonLabel = computed(() => {
return t('spreed', 'Enable live transcription (Live transcriptions app is not installed)')
Comment thread
nickvergessen marked this conversation as resolved.
})

const liveTranslationButtonLabel = computed(() => {
if (callViewStore.isLiveTranscriptionEnabled && languageType.value === LanguageType.Target) {
return t('spreed', 'Disable live translation')
Expand All @@ -95,6 +104,14 @@ const liveTranslationButtonLabel = computed(() => {
return t('spreed', 'Enable live translation (generated by AI)')
})

const hintOriginalButtonLabel = computed(() => {
return t('spreed', 'Original language')
})

const hintTranslationButtonLabel = computed(() => {
return t('spreed', 'Live translations app is not installed')
Comment thread
nickvergessen marked this conversation as resolved.
})

const originalLanguageButtonLabel = computed(() => {
const languageId = conversation.value.liveTranscriptionLanguageId || 'en'

Expand Down Expand Up @@ -557,7 +574,7 @@ useHotKey('r', toggleHandRaised)
:variant="callViewStore.isLiveTranscriptionEnabled ? 'secondary' : 'tertiary'"
:disabled="isLiveTranscriptionLoading"
:class="{
'translation-button': isLiveTranslationSupported,
'translation-button': isLiveTranslationSupported || hintTranslationSupported,
}"
@click="toggleLiveTranscriptionAndTranslation">
<template #icon>
Expand Down Expand Up @@ -604,6 +621,45 @@ useHotKey('r', toggleHandRaised)
{{ targetLanguageButtonLabel }}
</NcActionButton>
</NcActions>
<NcActions
v-else-if="hintTranslationSupported"
class="language-selector-button">
<template #icon>
<IconChevronUp :size="16" />
</template>
<NcActionButton
class="language-selector__action"
type="radio"
:modelValue="languageType"
:value="LanguageType.Original"
:title="hintOriginalButtonLabel">
{{ hintOriginalButtonLabel }}
</NcActionButton>
<NcActionSeparator />
<NcActionButton
class="language-selector__action"
type="radio"
disabled
:modelValue="languageType"
:value="LanguageType.Target"
:title="hintTranslationButtonLabel">
{{ hintTranslationButtonLabel }}
</NcActionButton>
</NcActions>
</div>
<div
v-else-if="hintTranscriptionSupported"
class="live-transcription-button-wrapper">
<NcButton
:title="hintTranscriptionButtonLabel"
:aria-label="hintTranscriptionButtonLabel"
variant="secondary"
disabled>
<template #icon>
<IconSubtitlesOutline
:size="20" />
</template>
</NcButton>
</div>

<NcButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@
:name="t('spreed', 'Live transcription')">
<LiveTranscriptionSettings :token="token" />
</NcAppSettingsSection>
<NcAppSettingsSection
v-else-if="hintLiveTranscription"
id="live-transcription"
:name="t('spreed', 'Live transcription')">
<NcCheckboxRadioSwitch
:description="t('spreed', 'Live transcriptions app is not installed')"
type="switch"
disabled>
{{ t('spreed', 'Enable live transcription') }}
</NcCheckboxRadioSwitch>
</NcAppSettingsSection>

<!-- Breakout rooms -->
<NcAppSettingsSection
Expand Down Expand Up @@ -144,7 +155,11 @@ import NotificationsSettings from './NotificationsSettings.vue'
import RecordingConsentSettings from './RecordingConsentSettings.vue'
import SipSettings from './SipSettings.vue'
import { CALL, CONFIG, CONVERSATION, PARTICIPANT } from '../../constants.ts'
import { getTalkConfig, hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import {
getTalkConfig,
hasTalkFeature,
showTalkFeatureHint,
} from '../../services/CapabilitiesManager.ts'
import { useActorStore } from '../../stores/actor.ts'

// FIXME Should use remote not local
Expand Down Expand Up @@ -267,6 +282,12 @@ export default {
&& this.selfIsOwnerOrModerator
},

hintLiveTranscription() {
return !this.isLiveTranscriptionSupported
&& this.selfIsOwnerOrModerator
&& showTalkFeatureHint(34)
},

canConfigureBreakoutRooms() {
return this.canFullModerate
&& (getTalkConfig(this.token, 'call', 'breakout-rooms') || false)
Expand Down
17 changes: 16 additions & 1 deletion src/components/LeftSidebar/LeftSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@
</template>
{{ t('spreed', 'Call a phone number') }}
</NcActionButton>
<NcActionButton
v-else-if="hintSipDialOut"
disabled
:description="t('spreed', 'SIP backend is not installed')">
<template #icon>
<IconPhoneOutline :size="20" />
</template>
{{ t('spreed', 'Call a phone number') }}
</NcActionButton>
</NcActions>
</TransitionWrapper>

Expand Down Expand Up @@ -348,7 +357,11 @@ import { useArrowNavigation } from '../../composables/useArrowNavigation.js'
import { useGetToken } from '../../composables/useGetToken.ts'
import { ATTENDEE, CONVERSATION } from '../../constants.ts'
import BrowserStorage from '../../services/BrowserStorage.js'
import { getTalkConfig, hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import {
getTalkConfig,
hasTalkFeature,
showTalkFeatureHint,
} from '../../services/CapabilitiesManager.ts'
import {
createLegacyConversation,
fetchNoteToSelfConversation,
Expand All @@ -372,6 +385,7 @@ const canModerateSipDialOut = hasTalkFeature('local', 'sip-support-dialout')
&& getTalkConfig('local', 'call', 'sip-enabled')
&& getTalkConfig('local', 'call', 'sip-dialout-enabled')
&& getTalkConfig('local', 'call', 'can-enable-sip')
const hintSipDialOut = !canModerateSipDialOut && showTalkFeatureHint(34)
const canNoteToSelf = hasTalkFeature('local', 'note-to-self')
const supportsArchive = hasTalkFeature('local', 'archived-conversations-v2')
const supportThreads = hasTalkFeature('local', 'threads')
Expand Down Expand Up @@ -458,6 +472,7 @@ export default {
talkHashStore,
isMobile,
canModerateSipDialOut,
hintSipDialOut,
canNoteToSelf,
supportsArchive,
supportThreads,
Expand Down
16 changes: 15 additions & 1 deletion src/components/MediaSettings/MediaSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@
class="checkbox">
{{ t('spreed', 'Start recording immediately with the call') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch
v-else-if="hintRecordingOption"
:description="t('spreed', 'Recording backend is not installed')"
disabled
class="checkbox">
{{ t('spreed', 'Start recording immediately with the call') }}
</NcCheckboxRadioSwitch>
<!-- Notify call option-->
<NcCheckboxRadioSwitch
v-if="showNotifyCallOption"
Expand Down Expand Up @@ -271,7 +278,10 @@ import { useGetToken } from '../../composables/useGetToken.ts'
import { useIsInCall } from '../../composables/useIsInCall.js'
import { ATTENDEE, AVATAR, CALL, CONFIG, PARTICIPANT, VIRTUAL_BACKGROUND } from '../../constants.ts'
import BrowserStorage from '../../services/BrowserStorage.js'
import { getTalkConfig } from '../../services/CapabilitiesManager.ts'
import {
getTalkConfig,
showTalkFeatureHint,
} from '../../services/CapabilitiesManager.ts'
import { useActorStore } from '../../stores/actor.ts'
import { useGuestNameStore } from '../../stores/guestName.ts'
import { useSettingsStore } from '../../stores/settings.ts'
Expand Down Expand Up @@ -516,6 +526,10 @@ export default {
return !this.hasCall && this.canModerateRecording && this.isBeforeJoinCall
},

hintRecordingOption() {
return !this.hasCall && this.canFullModerate && !(getTalkConfig(this.token, 'call', 'recording') || false) && this.isBeforeJoinCall && showTalkFeatureHint(34)
},

showUpdateChangesButton() {
return (this.isDeviceCheck
|| this.isInCall)
Expand Down
26 changes: 25 additions & 1 deletion src/components/RightSidebar/Participants/ParticipantsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
v-if="canAddPhones"
v-model:value="searchText"
@submit="addParticipants(participantPhoneItem)" />
<DialpadPanel
v-else-if="hintAddPhones"
:title="t('spreed', 'SIP backend is not installed')"
disabled />
</div>

<SelectPhoneNumber
Expand Down Expand Up @@ -72,6 +76,14 @@
:noResults="noResults"
:searchText="searchText"
@click="addParticipants" />

<SelectPhoneNumber
Comment thread
nickvergessen marked this conversation as resolved.
v-if="hintAddPhones"
v-model:participantPhoneItem="participantPhoneItem"
:name="t('spreed', 'Add a phone number')"
:value="searchText"
:hintAddPhones="true"
@select="addParticipants" />
</div>
</div>
</template>
Expand Down Expand Up @@ -99,7 +111,11 @@ import { useGetToken } from '../../../composables/useGetToken.ts'
import { useIsInCall } from '../../../composables/useIsInCall.js'
import { useSortParticipants } from '../../../composables/useSortParticipants.js'
import { ATTENDEE, CONVERSATION } from '../../../constants.ts'
import { getTalkConfig, hasTalkFeature } from '../../../services/CapabilitiesManager.ts'
import {
getTalkConfig,
hasTalkFeature,
showTalkFeatureHint,
} from '../../../services/CapabilitiesManager.ts'
import { autocompleteQuery } from '../../../services/coreService.ts'
import { EventBus } from '../../../services/EventBus.ts'
import { addParticipant } from '../../../services/participantsService.js'
Expand Down Expand Up @@ -227,6 +243,14 @@ export default {
return canModerateSipDialOut && this.conversation.canEnableSIP
},

hintAddPhones() {
const canModerateSipDialOut = hasTalkFeature(this.token, 'sip-support-dialout')
&& getTalkConfig(this.token, 'call', 'sip-enabled')
&& getTalkConfig(this.token, 'call', 'sip-dialout-enabled')
&& getTalkConfig(this.token, 'call', 'can-enable-sip')
return !canModerateSipDialOut && showTalkFeatureHint(34)
},

isSearching() {
return this.searchText !== ''
},
Expand Down
24 changes: 23 additions & 1 deletion src/components/SelectPhoneNumber.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,20 @@
<ul v-if="value">
<NcAppNavigationCaption :name="t('spreed', 'Phone numbers')" />
<NavigationHint v-if="errorHint" :hint="errorHint" />
<template v-if="libPhoneNumber">
<template v-if="hintAddPhones && libPhoneNumber">
<NcListItem :name="name" @click="selectPhoneNumber">
<template #icon>
<IconPhoneOutline :size="AVATAR.SIZE.DEFAULT" fillColor="var(--color-text-maxcontrast)" />
</template>
<template #name>
<em>{{ participantPhoneItem.phoneNumber }}</em>
</template>
<template #subname>
{{ t('spreed', 'SIP backend is not installed') }}
</template>
</NcListItem>
</template>
<template v-else-if="libPhoneNumber">
<NcListItem :name="name" @click="selectPhoneNumber">
<template #icon>
<IconPhoneOutline :size="AVATAR.SIZE.DEFAULT" />
Expand Down Expand Up @@ -57,6 +70,11 @@ export default {
type: Object,
required: true,
},

hintAddPhones: {
type: Boolean,
default: false,
},
},

emits: ['select', 'update:participantPhoneItem'],
Expand Down Expand Up @@ -118,6 +136,10 @@ export default {
methods: {
t,
selectPhoneNumber() {
if (this.hintAddPhones) {
return
}

this.$emit('select', this.participantPhoneItem)
},
},
Expand Down
22 changes: 21 additions & 1 deletion src/components/TopBar/TopBarMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@
{{ t('spreed', 'Stop recording') }}
</NcActionButton>
</template>
<template v-else-if="hintRecording">
<NcActionButton
disabled
:description="t('spreed', 'Recording backend is not installed')">
<template #icon>
<NcIconSvgWrapper
:svg="IconScreenRecordOutline"
:size="20" />
</template>
{{ t('spreed', 'Start recording') }}
</NcActionButton>
</template>

<NcActionSeparator v-if="!isOneToOneConversation || canModerateRecording" />
</template>
Expand Down Expand Up @@ -174,7 +186,11 @@ import {
} from '../../composables/useDocumentFullscreen.ts'
import { useIsInCall } from '../../composables/useIsInCall.js'
import { CALL, CONVERSATION, PARTICIPANT } from '../../constants.ts'
import { getTalkConfig, hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import {
getTalkConfig,
hasTalkFeature,
showTalkFeatureHint,
} from '../../services/CapabilitiesManager.ts'
import { generateAbsoluteUrl } from '../../utils/handleUrl.ts'
import { callParticipantCollection } from '../../utils/webrtc/index.js'

Expand Down Expand Up @@ -284,6 +300,10 @@ export default {
return getTalkConfig(this.token, 'call', 'recording') || false
},

hintRecording() {
return !this.canModerateRecording && showTalkFeatureHint(34)
},

canConfigureBreakoutRooms() {
if (this.conversation.type !== CONVERSATION.TYPE.GROUP || !this.canFullModerate) {
return false
Expand Down
10 changes: 10 additions & 0 deletions src/services/CapabilitiesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ export function getTalkConfig<
}
}

/**
* Check whether the feature hint should be shown
*
* @param featureHint FEATURE_HINT threshold according to lib/Config.php (e.g. Nextcloud version when hint or feature was introduced)
*/
export function showTalkFeatureHint(featureHint: number): boolean {
return (getTalkConfig('local', 'feature-hints', 'current') ?? 0) >= featureHint
&& (getTalkConfig('local', 'feature-hints', 'hidden') ?? 0) < featureHint
}

/**
* Check whether the app has capabilities published
*
Expand Down
Loading
Loading