Allow "voice mode" to be set as default on room creation
Also, hide it behind a flag in config (experimental_voice_mode)
This commit is contained in:
parent
3853f21f90
commit
afa38275f0
7 changed files with 246 additions and 244 deletions
|
|
@ -39,5 +39,6 @@
|
||||||
"siteId": "25"
|
"siteId": "25"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"experimental_voice_mode": true
|
||||||
}
|
}
|
||||||
|
|
@ -894,25 +894,25 @@ body {
|
||||||
|
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.with-right-label {
|
.with-right-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
& > * {
|
& > * {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
& > *:last-child {
|
& > *:last-child {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
.option-title {
|
.option-title {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-size: 16 * $chat-text-size;
|
font-size: 16 * $chat-text-size;
|
||||||
}
|
}
|
||||||
.option-text {
|
.option-text {
|
||||||
font-size: 13 * $chat-text-size;
|
font-size: 13 * $chat-text-size;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1131,6 +1131,21 @@ body {
|
||||||
border: 1px solid #808080 !important;
|
border: 1px solid #808080 !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-end;
|
||||||
|
color: black;
|
||||||
|
font-size: 14 * $chat-text-size;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 10px;
|
||||||
|
[dir="rtl"] & {
|
||||||
|
margin-left: initial;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
text-transform: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.room-link .v-input__slot::before {
|
.room-link .v-input__slot::before {
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,8 @@
|
||||||
"status_avatar_total": "Uploading avatar: {count} of {total}",
|
"status_avatar_total": "Uploading avatar: {count} of {total}",
|
||||||
"status_avatar": "Uploading avatar: {count}",
|
"status_avatar": "Uploading avatar: {count}",
|
||||||
"room_name_limit_error_msg": "Maximum 50 characters allowed",
|
"room_name_limit_error_msg": "Maximum 50 characters allowed",
|
||||||
"colon_not_allowed": "Colon is not allowed"
|
"colon_not_allowed": "Colon is not allowed",
|
||||||
|
"options": "Options"
|
||||||
},
|
},
|
||||||
"device_list": {
|
"device_list": {
|
||||||
"title": "DEVICES",
|
"title": "DEVICES",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
{{ $tc("room.invitations", invitationCount) }}
|
{{ $tc("room.invitations", invitationCount) }}
|
||||||
</div>
|
</div>
|
||||||
<ChatHeader class="chat-header flex-grow-0 flex-shrink-0" v-on:header-click="onHeaderClick" />
|
<ChatHeader class="chat-header flex-grow-0 flex-shrink-0" v-on:header-click="onHeaderClick" />
|
||||||
<AudioLayout ref="chatContainer" class="auto-audio-player-root" v-if="useAudioLayout" :room="room"
|
<AudioLayout ref="chatContainer" class="auto-audio-player-root" v-if="useVoiceMode" :room="room"
|
||||||
:events="events" :autoplay="!showRecorder"
|
:events="events" :autoplay="!showRecorder"
|
||||||
:timelineSet="timelineSet"
|
:timelineSet="timelineSet"
|
||||||
:readMarker="readMarker"
|
:readMarker="readMarker"
|
||||||
|
|
@ -13,11 +13,11 @@
|
||||||
v-on:loadprevious="handleScrolledToTop()"
|
v-on:loadprevious="handleScrolledToTop()"
|
||||||
v-on:mark-read="sendRR"
|
v-on:mark-read="sendRR"
|
||||||
/>
|
/>
|
||||||
<VoiceRecorder class="audio-layout" v-if="useAudioLayout" :micButtonRef="$refs.mic_button" :ptt="showRecorderPTT" :show="showRecorder"
|
<VoiceRecorder class="audio-layout" v-if="useVoiceMode" :micButtonRef="$refs.mic_button" :ptt="showRecorderPTT" :show="showRecorder"
|
||||||
v-on:close="showRecorder = false" v-on:file="onVoiceRecording" />
|
v-on:close="showRecorder = false" v-on:file="onVoiceRecording" :sendTypingIndicators="useVoiceMode" />
|
||||||
|
|
||||||
|
|
||||||
<div v-if="!useAudioLayout" class="chat-content flex-grow-1 flex-shrink-1" ref="chatContainer"
|
<div v-if="!useVoiceMode" class="chat-content flex-grow-1 flex-shrink-1" ref="chatContainer"
|
||||||
v-on:scroll="onScroll" @click="closeContextMenusIfOpen">
|
v-on:scroll="onScroll" @click="closeContextMenusIfOpen">
|
||||||
<div ref="messageOperationsStrut" class="message-operations-strut">
|
<div ref="messageOperationsStrut" class="message-operations-strut">
|
||||||
<message-operations ref="messageOperations" :style="opStyle" :emojis="recentEmojis" v-on:close="
|
<message-operations ref="messageOperations" :style="opStyle" :emojis="recentEmojis" v-on:close="
|
||||||
|
|
@ -69,10 +69,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Input area -->
|
<!-- Input area -->
|
||||||
<v-container v-if="!useAudioLayout && room" fluid :class="['input-area-outer', replyToEvent ? 'reply-to' : '']">
|
<v-container v-if="!useVoiceMode && room" fluid :class="['input-area-outer', replyToEvent ? 'reply-to' : '']">
|
||||||
<div :class="[replyToEvent ? 'iput-area-inner-box' : '']">
|
<div :class="[replyToEvent ? 'iput-area-inner-box' : '']">
|
||||||
<!-- "Scroll to end"-button -->
|
<!-- "Scroll to end"-button -->
|
||||||
<v-btn v-if="!useAudioLayout" class="scroll-to-end" v-show="showScrollToEnd" fab x-small elevation="0" color="black"
|
<v-btn v-if="!useVoiceMode" class="scroll-to-end" v-show="showScrollToEnd" fab x-small elevation="0" color="black"
|
||||||
@click.stop="scrollToEndOfTimeline">
|
@click.stop="scrollToEndOfTimeline">
|
||||||
<v-icon color="white">arrow_downward</v-icon>
|
<v-icon color="white">arrow_downward</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
@ -421,7 +421,7 @@ export default {
|
||||||
chatContainer() {
|
chatContainer() {
|
||||||
const container = this.$refs.chatContainer;
|
const container = this.$refs.chatContainer;
|
||||||
console.log("GOT CONTAINER", container);
|
console.log("GOT CONTAINER", container);
|
||||||
if (this.useAudioLayout) {
|
if (this.useVoiceMode) {
|
||||||
return container.$el;
|
return container.$el;
|
||||||
}
|
}
|
||||||
return container;
|
return container;
|
||||||
|
|
@ -522,15 +522,10 @@ export default {
|
||||||
me && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("redact", me.powerLevel);
|
me && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("redact", me.powerLevel);
|
||||||
return isAdmin;
|
return isAdmin;
|
||||||
},
|
},
|
||||||
useAudioLayout: {
|
useVoiceMode: {
|
||||||
get: function () {
|
get: function () {
|
||||||
if (this.room) {
|
if (!this.$config.experimental_voice_mode) return false;
|
||||||
const tags = this.room.tags;
|
return util.useVoiceMode(this.room);
|
||||||
if (tags && tags["ui_options"]) {
|
|
||||||
return tags["ui_options"]["voice_mode"] === 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -611,6 +606,12 @@ export default {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
showRecorder(show) {
|
||||||
|
if (this.useVoiceMode) {
|
||||||
|
// Send typing indicators when recorder UI is opened/closed
|
||||||
|
this.$matrix.matrixClient.sendTyping(this.roomId, show, 10 * 60 * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -826,7 +827,7 @@ export default {
|
||||||
const loadingDone = this.initialLoadDone;
|
const loadingDone = this.initialLoadDone;
|
||||||
this.$matrix.matrixClient.decryptEventIfNeeded(event, {});
|
this.$matrix.matrixClient.decryptEventIfNeeded(event, {});
|
||||||
|
|
||||||
if (this.initialLoadDone && !this.useAudioLayout) {
|
if (this.initialLoadDone && !this.useVoiceMode) {
|
||||||
this.paginateBackIfNeeded();
|
this.paginateBackIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1055,7 +1056,7 @@ export default {
|
||||||
.then((success) => {
|
.then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
this.events = this.timelineWindow.getEvents();
|
this.events = this.timelineWindow.getEvents();
|
||||||
if (!this.useAudioLayout) {
|
if (!this.useVoiceMode) {
|
||||||
this.scrollPosition.prepareFor("down");
|
this.scrollPosition.prepareFor("down");
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// restore scroll position!
|
// restore scroll position!
|
||||||
|
|
@ -1312,7 +1313,7 @@ export default {
|
||||||
|
|
||||||
let eventIdFirst = null;
|
let eventIdFirst = null;
|
||||||
let eventIdLast = null;
|
let eventIdLast = null;
|
||||||
if (!this.useAudioLayout) {
|
if (!this.useVoiceMode) {
|
||||||
const container = this.chatContainer;
|
const container = this.chatContainer;
|
||||||
const elFirst = util.getFirstVisibleElement(container);
|
const elFirst = util.getFirstVisibleElement(container);
|
||||||
const elLast = util.getLastVisibleElement(container);
|
const elLast = util.getLastVisibleElement(container);
|
||||||
|
|
|
||||||
|
|
@ -3,29 +3,23 @@
|
||||||
<div>
|
<div>
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<div class="room-name no-upper">{{ $t("new_room.new_room") }}</div>
|
<div class="room-name no-upper">{{ $t("new_room.new_room") }}</div>
|
||||||
<v-btn
|
<v-btn id="btn-back" text class="header-button-left" v-show="$navigation && $navigation.canPop()"
|
||||||
id="btn-back"
|
@click.stop="goBack" :disabled="step > steps.NAME_SET">
|
||||||
text
|
|
||||||
class="header-button-left"
|
|
||||||
v-show="$navigation && $navigation.canPop()"
|
|
||||||
@click.stop="goBack"
|
|
||||||
:disabled="step > steps.NAME_SET"
|
|
||||||
>
|
|
||||||
<v-icon>arrow_back</v-icon>
|
<v-icon>arrow_back</v-icon>
|
||||||
<span class="d-none d-sm-block">{{ $t("menu.back") }}</span>
|
<span class="d-none d-sm-block">{{ $t("menu.back") }}</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<!-- <v-btn
|
<!-- <v-btn
|
||||||
text
|
text
|
||||||
:disabled="
|
:disabled="
|
||||||
!roomName || (step != steps.INITIAL && step != steps.CREATED)
|
!roomName || (step != steps.INITIAL && step != steps.CREATED)
|
||||||
"
|
"
|
||||||
class="header-button-right"
|
class="header-button-right"
|
||||||
@click.stop="onCreate"
|
@click.stop="onCreate"
|
||||||
>
|
>
|
||||||
<span>{{
|
<span>{{
|
||||||
step == steps.CREATED ? $t("new_room.done") : $t("new_room.next")
|
step == steps.CREATED ? $t("new_room.done") : $t("new_room.next")
|
||||||
}}</span>
|
}}</span>
|
||||||
</v-btn> -->
|
</v-btn> -->
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -39,51 +33,43 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row cols="12" align="center" justify="center">
|
<v-row cols="12" align="center" justify="center">
|
||||||
<v-col sm="8" align="center">
|
<v-col sm="8" align="center">
|
||||||
<div class="text-left font-weight-light">{{ $t("new_room.name_room") }}</div>
|
<div class="text-left font-weight-light">{{ $t("new_room.name_room") }}</div>
|
||||||
<v-text-field
|
<v-text-field v-model="roomName" color="black" :rules="roomNamerules" counter="50" maxlength="50"
|
||||||
v-model="roomName"
|
background-color="white" v-on:keyup.enter="$refs.topic.focus()" :disabled="step > steps.INITIAL" autofocus
|
||||||
color="black"
|
solo @update:error="updateErrorState"></v-text-field>
|
||||||
:rules="roomNamerules"
|
<div class="text-left font-weight-light" v-show="roomName.length > 0">{{ $t("new_room.room_topic") }}</div>
|
||||||
counter="50"
|
<v-text-field v-model="roomTopic" v-show="roomName.length > 0" color="black" background-color="white"
|
||||||
maxlength="50"
|
v-on:keyup.enter="$refs.create.focus()" :disabled="step > steps.INITIAL" solo></v-text-field>
|
||||||
background-color="white"
|
|
||||||
v-on:keyup.enter="$refs.topic.focus()"
|
<!-- Our only option right now is voice mode, so if not enabled, hide the 'options' drop down as well -->
|
||||||
:disabled="step > steps.INITIAL"
|
<template v-if="$config.experimental_voice_mode">
|
||||||
autofocus
|
<div @click.stop="showOptions = !showOptions" v-show="roomName.length > 0" class="options clickable">
|
||||||
solo
|
<div>{{ $t("new_room.options") }}</div>
|
||||||
@update:error="updateErrorState"
|
<v-icon v-if="!showOptions">expand_more</v-icon>
|
||||||
></v-text-field>
|
<v-icon v-else>expand_less</v-icon>
|
||||||
<div class="text-left font-weight-light" v-show="roomName.length> 0">{{ $t("new_room.room_topic") }}</div>
|
</div>
|
||||||
<v-text-field
|
<v-card v-show="showOptions" class="account ma-3" flat>
|
||||||
v-model="roomTopic"
|
<v-card-text class="with-right-label">
|
||||||
v-show="roomName.length > 0"
|
<div>
|
||||||
color="black"
|
<div class="option-title">{{ $t('room_info.voice_mode') }}</div>
|
||||||
background-color="white"
|
<div class="option-text">{{ $t('room_info.voice_mode_info') }}</div>
|
||||||
v-on:keyup.enter="$refs.create.focus()"
|
</div>
|
||||||
:disabled="step > steps.INITIAL"
|
<v-switch v-model="useVoiceMode"></v-switch>
|
||||||
solo
|
</v-card-text>
|
||||||
></v-text-field>
|
</v-card>
|
||||||
<div class="error--text" v-if="roomCreationErrorMsg"> {{roomCreationErrorMsg}}</div>
|
</template>
|
||||||
<v-btn
|
|
||||||
id="btn-room-create"
|
<div class="error--text" v-if="roomCreationErrorMsg"> {{ roomCreationErrorMsg }}</div>
|
||||||
color="black"
|
<v-btn id="btn-room-create" color="black" depressed class="filled-button" @click.stop="onCreate"
|
||||||
depressed
|
:disabled="isDisabled">
|
||||||
class="filled-button"
|
<div v-if="status && !enterRoomDialog" class="text-center">
|
||||||
@click.stop="onCreate"
|
{{ status }}
|
||||||
:disabled="isDisabled"
|
<v-progress-circular v-if="step == steps.CREATING" indeterminate color="primary"
|
||||||
>
|
size="20"></v-progress-circular>
|
||||||
<div v-if="status && !enterRoomDialog" class="text-center">
|
</div>
|
||||||
{{ status }}
|
<span v-else>{{ $t("new_room.create") }}</span>
|
||||||
<v-progress-circular
|
</v-btn>
|
||||||
v-if="step == steps.CREATING"
|
|
||||||
indeterminate
|
|
||||||
color="primary"
|
|
||||||
size="20"
|
|
||||||
></v-progress-circular>
|
|
||||||
</div>
|
|
||||||
<span v-else>{{ $t("new_room.create") }}</span>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
@ -91,126 +77,101 @@
|
||||||
<v-fade-transition>
|
<v-fade-transition>
|
||||||
<!-- <div class="section ma-3" flat v-if="step > steps.INITIAL"> -->
|
<!-- <div class="section ma-3" flat v-if="step > steps.INITIAL"> -->
|
||||||
<!-- <div class="h4 text-left">{{ $t("new_room.join_permissions") }}</div>
|
<!-- <div class="h4 text-left">{{ $t("new_room.join_permissions") }}</div>
|
||||||
<div class="h2 text-left">
|
<div class="h2 text-left">
|
||||||
{{ $t("new_room.set_join_permissions") }}
|
{{ $t("new_room.set_join_permissions") }}
|
||||||
</div>
|
</div>
|
||||||
<div>{{ $t("new_room.join_permissions_info") }}</div>
|
<div>{{ $t("new_room.join_permissions_info") }}</div>
|
||||||
<v-select
|
<v-select
|
||||||
:disabled="step >= steps.CREATING"
|
:disabled="step >= steps.CREATING"
|
||||||
:items="joinRules"
|
:items="joinRules"
|
||||||
class="mt-4"
|
class="mt-4"
|
||||||
v-model="joinRule"
|
v-model="joinRule"
|
||||||
item-value="id"
|
item-value="id"
|
||||||
>
|
>
|
||||||
<template v-slot:selection="{ item }">
|
<template v-slot:selection="{ item }">
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:item="{ item, attrs, on }">
|
<template v-slot:item="{ item, attrs, on }">
|
||||||
<v-list-item v-on="on" v-bind="attrs" #default="{ active }">
|
<v-list-item v-on="on" v-bind="attrs" #default="{ active }">
|
||||||
<v-list-item-avatar>
|
<v-list-item-avatar>
|
||||||
<v-icon class="grey lighten-1" dark>{{ item.icon }}</v-icon>
|
<v-icon class="grey lighten-1" dark>{{ item.icon }}</v-icon>
|
||||||
</v-list-item-avatar>
|
</v-list-item-avatar>
|
||||||
<v-list-item-content>
|
<v-list-item-content>
|
||||||
<v-list-item-title v-text="item.text"></v-list-item-title>
|
<v-list-item-title v-text="item.text"></v-list-item-title>
|
||||||
<v-list-item-subtitle
|
<v-list-item-subtitle
|
||||||
v-text="item.descr"
|
v-text="item.descr"
|
||||||
></v-list-item-subtitle>
|
></v-list-item-subtitle>
|
||||||
</v-list-item-content>
|
</v-list-item-content>
|
||||||
<v-list-item-action>
|
<v-list-item-action>
|
||||||
<v-btn icon v-if="active">
|
<v-btn icon v-if="active">
|
||||||
<v-icon color="grey lighten-1">check</v-icon>
|
<v-icon color="grey lighten-1">check</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-list-item-action>
|
</v-list-item-action>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</template>
|
</template>
|
||||||
</v-select>
|
</v-select>
|
||||||
|
|
||||||
<v-divider style="margin-bottom: 20px" />
|
<v-divider style="margin-bottom: 20px" />
|
||||||
|
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-if="publicRoomLink"
|
v-if="publicRoomLink"
|
||||||
:value="publicRoomLink"
|
:value="publicRoomLink"
|
||||||
class="room-link"
|
class="room-link"
|
||||||
readonly
|
readonly
|
||||||
filled
|
filled
|
||||||
background-color="transparent"
|
background-color="transparent"
|
||||||
append-icon="content_copy"
|
append-icon="content_copy"
|
||||||
type="text"
|
type="text"
|
||||||
@click:append.stop="copyRoomLink"
|
@click:append.stop="copyRoomLink"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-else-if="joinRule == 'public'"
|
v-else-if="joinRule == 'public'"
|
||||||
:loading="step == steps.CREATING"
|
:loading="step == steps.CREATING"
|
||||||
block
|
block
|
||||||
depressed
|
depressed
|
||||||
class="outlined-button"
|
class="outlined-button"
|
||||||
@click.stop="getPublicLink"
|
@click.stop="getPublicLink"
|
||||||
><v-icon class="me-2">link</v-icon
|
><v-icon class="me-2">link</v-icon
|
||||||
>{{ $t("new_room.get_link") }}</v-btn
|
>{{ $t("new_room.get_link") }}</v-btn
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-else-if="joinRule == 'invite'"
|
v-else-if="joinRule == 'invite'"
|
||||||
block
|
block
|
||||||
depressed
|
depressed
|
||||||
class="outlined-button"
|
class="outlined-button"
|
||||||
@click.stop="addPeople"
|
@click.stop="addPeople"
|
||||||
><v-icon class="me-2">person_add</v-icon
|
><v-icon class="me-2">person_add</v-icon
|
||||||
>{{ $t("new_room.add_people") }}</v-btn
|
>{{ $t("new_room.add_people") }}</v-btn
|
||||||
>
|
>
|
||||||
|
|
||||||
<div v-if="publicRoomLinkCopied" class="link-copied">
|
<div v-if="publicRoomLinkCopied" class="link-copied">
|
||||||
{{ $t("new_room.link_copied") }}
|
{{ $t("new_room.link_copied") }}
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
<!-- <div v-if="status && !enterRoomDialog" class="text-center">
|
<!-- <div v-if="status && !enterRoomDialog" class="text-center">
|
||||||
<v-progress-circular
|
<v-progress-circular
|
||||||
v-if="step == steps.CREATING"
|
v-if="step == steps.CREATING"
|
||||||
indeterminate
|
indeterminate
|
||||||
color="primary"
|
color="primary"
|
||||||
size="20"
|
size="20"
|
||||||
></v-progress-circular>
|
></v-progress-circular>
|
||||||
{{ status }}
|
{{ status }}
|
||||||
</div> -->
|
</div> -->
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
</v-fade-transition>
|
</v-fade-transition>
|
||||||
<input
|
<input id="room-avatar-picker" ref="avatar" type="file" name="avatar" @change="handlePickedAvatar($event)"
|
||||||
id="room-avatar-picker"
|
accept="image/*" class="d-none" />
|
||||||
ref="avatar"
|
<v-dialog v-model="enterRoomDialog" :width="$vuetify.breakpoint.smAndUp ? '50%' : '90%'">
|
||||||
type="file"
|
|
||||||
name="avatar"
|
|
||||||
@change="handlePickedAvatar($event)"
|
|
||||||
accept="image/*"
|
|
||||||
class="d-none"
|
|
||||||
/>
|
|
||||||
<v-dialog
|
|
||||||
v-model="enterRoomDialog"
|
|
||||||
:width="$vuetify.breakpoint.smAndUp ? '50%' : '90%'"
|
|
||||||
>
|
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-container v-if="canEditProfile" class="pa-10">
|
<v-container v-if="canEditProfile" class="pa-10">
|
||||||
<v-row class="align-center">
|
<v-row class="align-center">
|
||||||
<v-col class="py-0">
|
<v-col class="py-0">
|
||||||
<div class="text-left font-weight-bold">{{ $t("join.choose_name") }}</div>
|
<div class="text-left font-weight-bold">{{ $t("join.choose_name") }}</div>
|
||||||
<v-select
|
<v-select ref="avatar" :items="availableAvatars" cache-items outlined dense @change="selectAvatar"
|
||||||
ref="avatar"
|
:value="availableAvatars[0]" single-line autofocus>
|
||||||
:items="availableAvatars"
|
|
||||||
cache-items
|
|
||||||
outlined
|
|
||||||
dense
|
|
||||||
@change="selectAvatar"
|
|
||||||
:value="availableAvatars[0]"
|
|
||||||
single-line
|
|
||||||
autofocus
|
|
||||||
>
|
|
||||||
<template v-slot:selection>
|
<template v-slot:selection>
|
||||||
<v-text-field
|
<v-text-field background-color="transparent" solo flat hide-details @click.native.stop="{}"
|
||||||
background-color="transparent"
|
v-model="selectedProfile.name"></v-text-field>
|
||||||
solo
|
|
||||||
flat
|
|
||||||
hide-details
|
|
||||||
@click.native.stop="{}"
|
|
||||||
v-model="selectedProfile.name"
|
|
||||||
></v-text-field>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:item="data">
|
<template v-slot:item="data">
|
||||||
<v-avatar size="32">
|
<v-avatar size="32">
|
||||||
|
|
@ -219,33 +180,23 @@
|
||||||
<div class="ms-2">{{ data.item.name }}</div>
|
<div class="ms-2">{{ data.item.name }}</div>
|
||||||
</template>
|
</template>
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="2" class="py-0">
|
<v-col cols="2" class="py-0">
|
||||||
<v-avatar @click="showAvatarPickerList">
|
<v-avatar @click="showAvatarPickerList">
|
||||||
<v-img v-if="selectedProfile" :src="selectedProfile.image" />
|
<v-img v-if="selectedProfile" :src="selectedProfile.image" />
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row class="mt-0">
|
<v-row class="mt-0">
|
||||||
<v-col class="py-0">
|
<v-col class="py-0">
|
||||||
<v-checkbox
|
<v-checkbox id="chk-remember-me" class="mt-0" v-model="rememberMe" @change="onRememberMe"
|
||||||
id="chk-remember-me"
|
:label="$t('join.remember_me')" />
|
||||||
class="mt-0"
|
|
||||||
v-model="rememberMe"
|
|
||||||
@change="onRememberMe"
|
|
||||||
:label="$t('join.remember_me')"
|
|
||||||
/>
|
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-btn
|
<v-btn color="black" depressed class="filled-button" @click.stop="onEnterRoom"
|
||||||
color="black"
|
:disabled="!selectedProfile.name">
|
||||||
depressed
|
{{ $t("join.enter_room") }}
|
||||||
class="filled-button"
|
</v-btn>
|
||||||
@click.stop="onEnterRoom"
|
|
||||||
:disabled="!selectedProfile.name"
|
|
||||||
>
|
|
||||||
{{ $t("join.enter_room") }}
|
|
||||||
</v-btn>
|
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
@ -253,7 +204,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import util from "../plugins/utils";
|
import util, { ROOM_TYPE_VOICE_MODE } from "../plugins/utils";
|
||||||
import rememberMeMixin from "./rememberMeMixin";
|
import rememberMeMixin from "./rememberMeMixin";
|
||||||
|
|
||||||
const steps = Object.freeze({
|
const steps = Object.freeze({
|
||||||
|
|
@ -265,7 +216,7 @@ const steps = Object.freeze({
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CreateRoom",
|
name: "CreateRoom",
|
||||||
mixins:[rememberMeMixin],
|
mixins: [rememberMeMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
steps,
|
steps,
|
||||||
|
|
@ -305,7 +256,9 @@ export default {
|
||||||
v => !v.includes(':') || this.$t("new_room.colon_not_allowed")
|
v => !v.includes(':') || this.$t("new_room.colon_not_allowed")
|
||||||
],
|
],
|
||||||
roomNameHasError: false,
|
roomNameHasError: false,
|
||||||
roomCreationErrorMsg: ""
|
roomCreationErrorMsg: "",
|
||||||
|
showOptions: false,
|
||||||
|
useVoiceMode: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -314,7 +267,7 @@ export default {
|
||||||
this.availableAvatars = util.getDefaultAvatars();
|
this.availableAvatars = util.getDefaultAvatars();
|
||||||
this.selectAvatar(
|
this.selectAvatar(
|
||||||
this.availableAvatars[
|
this.availableAvatars[
|
||||||
Math.floor(Math.random() * this.availableAvatars.length)
|
Math.floor(Math.random() * this.availableAvatars.length)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -359,7 +312,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
onCreate() {
|
onCreate() {
|
||||||
if(this.currentUser) {
|
if (this.currentUser) {
|
||||||
this.onEnterRoom();
|
this.onEnterRoom();
|
||||||
} else {
|
} else {
|
||||||
this.enterRoomDialog = true;
|
this.enterRoomDialog = true;
|
||||||
|
|
@ -486,6 +439,11 @@ export default {
|
||||||
// Add topic
|
// Add topic
|
||||||
createRoomOptions.topic = this.roomTopic;
|
createRoomOptions.topic = this.roomTopic;
|
||||||
}
|
}
|
||||||
|
if (this.useVoiceMode) {
|
||||||
|
createRoomOptions.creation_content = {
|
||||||
|
type: ROOM_TYPE_VOICE_MODE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this.$matrix
|
return this.$matrix
|
||||||
.getLoginPromise()
|
.getLoginPromise()
|
||||||
|
|
@ -592,7 +550,7 @@ export default {
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.status = ""
|
this.status = ""
|
||||||
this.roomCreationErrorMsg = (error.data && error.data.error) || error.message || error.toString();
|
this.roomCreationErrorMsg = (error.data && error.data.error) || error.message || error.toString();
|
||||||
this.step = steps.INITIAL; // revert
|
this.step = steps.INITIAL; // revert
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<v-card class="account ma-3" flat>
|
<v-card class="account ma-3" flat v-if="$config.experimental_voice_mode">
|
||||||
<v-card-title class="h2 with-right-label"><div>{{ $t("room_info.experimental_features") }}</div><div></div></v-card-title>
|
<v-card-title class="h2 with-right-label"><div>{{ $t("room_info.experimental_features") }}</div><div></div></v-card-title>
|
||||||
<v-card-text class="with-right-label">
|
<v-card-text class="with-right-label">
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -173,7 +173,7 @@
|
||||||
<div class="option-text">{{ $t('room_info.voice_mode_info') }}</div>
|
<div class="option-text">{{ $t('room_info.voice_mode_info') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<v-switch
|
<v-switch
|
||||||
v-model="useAudioLayout"
|
v-model="useVoiceMode"
|
||||||
></v-switch>
|
></v-switch>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
@ -376,15 +376,9 @@ export default {
|
||||||
return "";
|
return "";
|
||||||
},
|
},
|
||||||
|
|
||||||
useAudioLayout: {
|
useVoiceMode: {
|
||||||
get: function () {
|
get: function () {
|
||||||
if (this.room) {
|
return util.useVoiceMode(this.room);
|
||||||
const tags = this.room.tags;
|
|
||||||
if (tags && tags["ui_options"]) {
|
|
||||||
return tags["ui_options"]["voice_mode"] === 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
set: function (audioLayout) {
|
set: function (audioLayout) {
|
||||||
if (this.room && this.room.tags) {
|
if (this.room && this.room.tags) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import * as ContentHelpers from "matrix-js-sdk/lib/content-helpers";
|
||||||
import dataUriToBuffer from "data-uri-to-buffer";
|
import dataUriToBuffer from "data-uri-to-buffer";
|
||||||
import ImageResize from "image-resize";
|
import ImageResize from "image-resize";
|
||||||
|
|
||||||
|
export const ROOM_TYPE_VOICE_MODE = "im.keanu.room_type_voice";
|
||||||
|
|
||||||
const sizeOf = require("image-size");
|
const sizeOf = require("image-size");
|
||||||
|
|
||||||
var dayjs = require('dayjs');
|
var dayjs = require('dayjs');
|
||||||
|
|
@ -424,6 +426,36 @@ class Util {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 'true' if we should use voice mode for the given room.
|
||||||
|
*
|
||||||
|
* The default value is given by the room itself. If the "type" of the
|
||||||
|
* room is set to 'im.keanu.room_type_voice' then we default to voice mode,
|
||||||
|
* else not. The user can then override this default by flipping the "voice mode"
|
||||||
|
* swicth on room settings (it will be persisted as a user specific tag on the room)
|
||||||
|
*/
|
||||||
|
useVoiceMode(roomOrNull) {
|
||||||
|
if (roomOrNull) {
|
||||||
|
const room = roomOrNull;
|
||||||
|
|
||||||
|
// Have we changed our local view mode of this room?
|
||||||
|
const tags = room.tags;
|
||||||
|
if (tags && tags["ui_options"]) {
|
||||||
|
return tags["ui_options"]["voice_mode"] === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Was the room created with a voice mode type?
|
||||||
|
const createEvent = room.currentState.getStateEvents(
|
||||||
|
"m.room.create",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
if (createEvent) {
|
||||||
|
return createEvent.getContent().type === ROOM_TYPE_VOICE_MODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Generate a random user name */
|
/** Generate a random user name */
|
||||||
randomUser(prefix) {
|
randomUser(prefix) {
|
||||||
var pfx = prefix ? prefix.replace(/[^0-9a-zA-Z\-_]/gi, '') : null;
|
var pfx = prefix ? prefix.replace(/[^0-9a-zA-Z\-_]/gi, '') : null;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue