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
3 changes: 2 additions & 1 deletion docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@

## 17
* `avatar` - Avatar of conversation
* `config => chat => translations` - List of translations tuples, JSON encoded sample `{"from":"de","fromLabel":"German","to":"en","toLabel":"English"}`. Those tuples should be provided as options when translating chat messages.
* ~~`config => chat => translations` - List of translations tuples, JSON encoded sample `{"from":"de","fromLabel":"German","to":"en","toLabel":"English"}`. Those tuples should be provided as options when translating chat messages.~~ Due to some providers the list was too big causing issues in various clients. So the capability was replaced by boolean `config => chat => has-translation-providers` in Talk 18.
* `config => call => predefined-backgrounds` - List of predefined virtual backgrounds. The files are in Talks img/ folder, accessible via the normal image path methods. The list is cached for 5 minutes.
* `config => call => can-upload-background` - Boolean flag whether the user can upload a custom virtual background (requires an account and non-zero quota). Uploads should be done to Talk/Backgrounds/ (respecting the user's attachment directory setting).
* `config => call => supported-reactions` - A list of emojis supported as call reactions. If the list is absent or empty, clients should not show the emoji reaction option in calls.
Expand All @@ -129,3 +129,4 @@

## 18
* `session-state` - Sessions can mark themselves as inactive, so the participant receives notifications again
* `config => chat => has-translation-providers` - When true, translation tuples can be loaded from the [OCS Translation API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-translation-api.html#get-available-translation-options).
3 changes: 1 addition & 2 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ public function getCapabilities(): array {
'chat' => [
'max-length' => ChatManager::MAX_CHAT_LENGTH,
'read-privacy' => Participant::PRIVACY_PUBLIC,
// Transform the JsonSerializable language tuples to arrays
'translations' => json_decode(json_encode($this->translationManager->getLanguages()), true),
'has-translation-providers' => $this->translationManager->hasProviders(),
'typing-privacy' => Participant::PRIVACY_PUBLIC,
],
'conversations' => [
Expand Down
6 changes: 4 additions & 2 deletions src/components/MessagesList/MessagesGroup/Message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ the main body of the message as well as a quote.
</div>
</div>

<MessageTranslateDialog v-if="isTranslateDialogOpen"
<MessageTranslateDialog v-if="isTranslationAvailable && isTranslateDialogOpen"
:message="message"
:rich-parameters="richParameters"
@close="isTranslateDialogOpen = false" />
Expand Down Expand Up @@ -283,7 +283,9 @@ import { EventBus } from '../../../../services/EventBus.js'
import { useGuestNameStore } from '../../../../stores/guestName.js'
import { getItemTypeFromMessage } from '../../../../utils/getItemTypeFromMessage.js'

const isTranslationAvailable = getCapabilities()?.spreed?.config?.chat?.translations?.length > 0
const isTranslationAvailable = getCapabilities()?.spreed?.config?.chat?.['has-translation-providers']
// Fallback for the desktop client when connecting to Talk 17
?? getCapabilities()?.spreed?.config?.chat?.translations?.length > 0

/**
* @property {object} scrollerBoundingClientRect provided by MessageList.vue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
import ArrowRight from 'vue-material-design-icons/ArrowRight.vue'
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'

import { getCapabilities } from '@nextcloud/capabilities'
import { showError, showSuccess } from '@nextcloud/dialogs'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
Expand All @@ -89,9 +88,7 @@ import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import NcRichText from '@nextcloud/vue/dist/Components/NcRichText.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'

import { translateText } from '../../../../../services/messagesService.js'

const availableLanguages = getCapabilities()?.spreed?.config?.chat?.translations
import { getTranslationLanguages, translateText } from '../../../../../services/messagesService.js'

export default {
name: 'MessageTranslateDialog',
Expand Down Expand Up @@ -119,13 +116,10 @@ export default {

emits: ['close'],

setup() {
return { availableLanguages }
},

data() {
return {
isMounted: false,
availableLanguages: null,
selectedFrom: null,
selectedTo: null,
isLoading: false,
Expand All @@ -140,13 +134,13 @@ export default {

sourceTree() {
const tree = {}
const uniqueSourceLanguages = Array.from(new Set(this.availableLanguages.map(element => element.from)))
const uniqueSourceLanguages = Array.from(new Set(this.availableLanguages?.map(element => element.from)))

uniqueSourceLanguages.forEach(language => {
tree[language] = {
id: language,
label: this.availableLanguages.find(element => element.from === language)?.fromLabel,
translations: this.availableLanguages.filter(element => element.from === language).map(model => ({
label: this.availableLanguages?.find(element => element.from === language)?.fromLabel,
translations: this.availableLanguages?.filter(element => element.from === language).map(model => ({
id: model.to,
label: model.toLabel,
})),
Expand All @@ -158,13 +152,13 @@ export default {

translationTree() {
const tree = {}
const uniqueTranslateLanguages = Array.from(new Set(this.availableLanguages.map(element => element.to)))
const uniqueTranslateLanguages = Array.from(new Set(this.availableLanguages?.map(element => element.to)))

uniqueTranslateLanguages.forEach(language => {
tree[language] = {
id: language,
label: this.availableLanguages.find(element => element.to === language)?.toLabel,
sources: this.availableLanguages.filter(element => element.to === language).map(model => ({
label: this.availableLanguages?.find(element => element.to === language)?.toLabel,
sources: this.availableLanguages?.filter(element => element.to === language).map(model => ({
id: model.from,
label: model.fromLabel,
})),
Expand Down Expand Up @@ -202,6 +196,11 @@ export default {
},
},

async created() {
const response = await getTranslationLanguages()
this.availableLanguages = response.data.ocs.data.languages
},

mounted() {
this.selectedTo = this.optionsTo.find(language => language.id === this.userLanguage) || null

Expand Down
18 changes: 5 additions & 13 deletions tests/php/CapabilitiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
use OCP\IUser;
use OCP\IUserSession;
use OCP\Translation\ITranslationManager;
use OCP\Translation\LanguageTuple;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;

Expand Down Expand Up @@ -206,7 +205,7 @@ public function testGetCapabilitiesGuest(): void {
'chat' => [
'max-length' => 32000,
'read-privacy' => 0,
'translations' => [],
'has-translation-providers' => false,
'typing-privacy' => 0,
],
'conversations' => [
Expand Down Expand Up @@ -330,7 +329,7 @@ public function testGetCapabilitiesUserAllowed(bool $isNotAllowed, bool $canCrea
'chat' => [
'max-length' => 32000,
'read-privacy' => $readPrivacy,
'translations' => [],
'has-translation-providers' => false,
'typing-privacy' => 0,
],
'conversations' => [
Expand Down Expand Up @@ -447,17 +446,10 @@ public function testCapabilitiesTranslations(): void {
$this->cacheFactory,
);

$translations = [];
$translations[] = new LanguageTuple('de', 'de Label', 'en', 'en Label');
$translations[] = new LanguageTuple('de_DE', 'de_DE Label', 'en', 'en Label');

$this->translationManager->method('getLanguages')
->willReturn($translations);
$this->translationManager->method('hasProviders')
->willReturn(true);

$data = json_decode(json_encode($capabilities->getCapabilities(), JSON_THROW_ON_ERROR), true);
$this->assertEquals([
['from' => 'de', 'fromLabel' => 'de Label', 'to' => 'en', 'toLabel' => 'en Label'],
['from' => 'de_DE', 'fromLabel' => 'de_DE Label', 'to' => 'en', 'toLabel' => 'en Label'],
], $data['spreed']['config']['chat']['translations']);
$this->assertEquals(true, $data['spreed']['config']['chat']['has-translation-providers']);
}
}