Merge pull request #13552 from antobinary/2.4-into-develop
chore: Merge 2.4 branch into develop
This commit is contained in:
commit
bb898fec8e
@ -15,7 +15,7 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait {
|
||||
|
||||
def handleCreateBreakoutRoomsCmdMsg(msg: CreateBreakoutRoomsCmdMsg, state: MeetingState2x): MeetingState2x = {
|
||||
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to create breakout room for meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId,
|
||||
|
@ -15,7 +15,7 @@ trait ChangeLockSettingsInMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
|
||||
def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
|
||||
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to change lock settings"
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -12,7 +12,7 @@ trait ChangeUserRoleCmdMsgHdlr extends RightsManagementTrait {
|
||||
val outGW: OutMsgRouter
|
||||
|
||||
def handleChangeUserRoleCmdMsg(msg: ChangeUserRoleCmdMsg) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to change user role in meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -23,7 +23,7 @@ trait EjectUserFromMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
PermissionCheck.VIEWER_LEVEL,
|
||||
liveMeeting.users2x,
|
||||
msg.header.userId
|
||||
)) {
|
||||
) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
|
||||
val reason = "No permission to eject user from meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -15,7 +15,7 @@ trait LogoutAndEndMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
val eventBus: InternalEventBus
|
||||
|
||||
def handleLogoutAndEndMeetingCmdMsg(msg: LogoutAndEndMeetingCmdMsg, state: MeetingState2x): Unit = {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to end meeting on logout."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -13,7 +13,7 @@ trait UpdateWebcamsOnlyForModeratorCmdMsgHdlr extends RightsManagementTrait {
|
||||
|
||||
def handleUpdateWebcamsOnlyForModeratorCmdMsg(msg: UpdateWebcamsOnlyForModeratorCmdMsg) {
|
||||
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to change lock settings"
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -50,7 +50,7 @@ object Users2x {
|
||||
def findAllExpiredUserLeftFlags(users: Users2x, meetingExpireWhenLastUserLeftInMs: Long): Vector[UserState] = {
|
||||
if (meetingExpireWhenLastUserLeftInMs > 0) {
|
||||
users.toVector filter (u => u.userLeftFlag.left && u.userLeftFlag.leftOn != 0 &&
|
||||
System.currentTimeMillis() - u.userLeftFlag.leftOn > 1000)
|
||||
System.currentTimeMillis() - u.userLeftFlag.leftOn > 30000)
|
||||
} else {
|
||||
// When meetingExpireWhenLastUserLeftInMs is set zero we need to
|
||||
// remove user right away to end the meeting as soon as possible.
|
||||
|
@ -12,7 +12,7 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
||||
val outGW: OutMsgRouter
|
||||
|
||||
def handleMuteAllExceptPresentersCmdMsg(msg: MuteAllExceptPresentersCmdMsg) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to mute all except presenters."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -13,7 +13,7 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
|
||||
def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {
|
||||
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to mute meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -14,7 +14,7 @@ trait SetGuestPolicyMsgHdlr extends RightsManagementTrait {
|
||||
val outGW: OutMsgRouter
|
||||
|
||||
def handleSetGuestPolicyMsg(msg: SetGuestPolicyCmdMsg): Unit = {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
|
||||
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId) || liveMeeting.props.meetingProp.isBreakout) {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
val reason = "No permission to set guest policy in meeting."
|
||||
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
|
||||
|
@ -28,6 +28,14 @@ public class LearningDashboardService {
|
||||
private static Logger log = LoggerFactory.getLogger(LearningDashboardService.class);
|
||||
private static String learningDashboardFilesDir = "/var/bigbluebutton/learning-dashboard";
|
||||
|
||||
public File getJsonDataFile(String meetingId, String learningDashboardAccessToken) {
|
||||
File baseDir = new File(this.getDestinationBaseDirectoryName(meetingId,learningDashboardAccessToken));
|
||||
if (!baseDir.exists()) baseDir.mkdirs();
|
||||
|
||||
File jsonFile = new File(baseDir.getAbsolutePath() + File.separatorChar + "learning_dashboard_data.json");
|
||||
return jsonFile;
|
||||
}
|
||||
|
||||
public void writeJsonDataFile(String meetingId, String learningDashboardAccessToken, String activityJson) {
|
||||
|
||||
try {
|
||||
@ -36,10 +44,7 @@ public class LearningDashboardService {
|
||||
return;
|
||||
}
|
||||
|
||||
File baseDir = new File(this.getDestinationBaseDirectoryName(meetingId,learningDashboardAccessToken));
|
||||
if (!baseDir.exists()) baseDir.mkdirs();
|
||||
|
||||
File jsonFile = new File(baseDir.getAbsolutePath() + File.separatorChar + "learning_dashboard_data.json");
|
||||
File jsonFile = this.getJsonDataFile(meetingId,learningDashboardAccessToken);
|
||||
|
||||
FileOutputStream fileOutput = new FileOutputStream(jsonFile);
|
||||
fileOutput.write(activityJson.getBytes());
|
||||
|
@ -0,0 +1,40 @@
|
||||
package org.bigbluebutton.api.model.request;
|
||||
|
||||
import org.bigbluebutton.api.model.constraint.UserSessionConstraint;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
public class LearningDashboard implements Request<LearningDashboard.Params> {
|
||||
|
||||
public enum Params implements RequestParameters {
|
||||
SESSION_TOKEN("sessionToken");
|
||||
|
||||
private final String value;
|
||||
|
||||
Params(String value) { this.value = value; }
|
||||
|
||||
public String getValue() { return value; }
|
||||
}
|
||||
|
||||
@UserSessionConstraint
|
||||
private String sessionToken;
|
||||
|
||||
public String getSessionToken() {
|
||||
return sessionToken;
|
||||
}
|
||||
|
||||
public void setSessionToken(String sessionToken) {
|
||||
this.sessionToken = sessionToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateFromParamsMap(Map<String, String[]> params) {
|
||||
if(params.containsKey(LearningDashboard.Params.SESSION_TOKEN.getValue())) setSessionToken(params.get(LearningDashboard.Params.SESSION_TOKEN.getValue())[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertParamsFromString() {
|
||||
|
||||
}
|
||||
}
|
@ -39,7 +39,8 @@ public class ValidationService {
|
||||
GUEST_WAIT("guestWait", RequestType.GET),
|
||||
ENTER("enter", RequestType.GET),
|
||||
STUNS("stuns", RequestType.GET),
|
||||
SIGN_OUT("signOut", RequestType.GET);
|
||||
SIGN_OUT("signOut", RequestType.GET),
|
||||
LEARNING_DASHBOARD("learningDashboard", RequestType.GET);
|
||||
|
||||
private final String name;
|
||||
private final RequestType requestType;
|
||||
@ -133,6 +134,9 @@ public class ValidationService {
|
||||
case SIGN_OUT:
|
||||
request = new SignOut();
|
||||
break;
|
||||
case LEARNING_DASHBOARD:
|
||||
request = new LearningDashboard();
|
||||
break;
|
||||
}
|
||||
case POST:
|
||||
checksum = new PostChecksum(apiCall.getName(), checksumValue, params);
|
||||
|
@ -17,6 +17,8 @@ class App extends React.Component {
|
||||
tab: 'overview',
|
||||
meetingId: '',
|
||||
learningDashboardAccessToken: '',
|
||||
ldAccessTokenCopied: false,
|
||||
sessionToken: '',
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +32,7 @@ class App extends React.Component {
|
||||
setDashboardParams() {
|
||||
let learningDashboardAccessToken = '';
|
||||
let meetingId = '';
|
||||
let sessionToken = '';
|
||||
|
||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
const params = Object.fromEntries(urlSearchParams.entries());
|
||||
@ -38,6 +41,10 @@ class App extends React.Component {
|
||||
meetingId = params.meeting;
|
||||
}
|
||||
|
||||
if (typeof params.sessionToken !== 'undefined') {
|
||||
sessionToken = params.sessionToken;
|
||||
}
|
||||
|
||||
if (typeof params.report !== 'undefined') {
|
||||
learningDashboardAccessToken = params.report;
|
||||
} else {
|
||||
@ -56,11 +63,12 @@ class App extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ learningDashboardAccessToken, meetingId }, this.fetchActivitiesJson);
|
||||
this.setState({ learningDashboardAccessToken, meetingId, sessionToken },
|
||||
this.fetchActivitiesJson);
|
||||
}
|
||||
|
||||
fetchActivitiesJson() {
|
||||
const { learningDashboardAccessToken, meetingId } = this.state;
|
||||
const { learningDashboardAccessToken, meetingId, sessionToken } = this.state;
|
||||
|
||||
if (learningDashboardAccessToken !== '') {
|
||||
fetch(`${meetingId}/${learningDashboardAccessToken}/learning_dashboard_data.json`)
|
||||
@ -71,14 +79,48 @@ class App extends React.Component {
|
||||
}).catch(() => {
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
} else if (sessionToken !== '') {
|
||||
const url = new URL('/bigbluebutton/api/learningDashboard', window.location);
|
||||
fetch(`${url}?sessionToken=${sessionToken}`)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
if (json.response.returncode === 'SUCCESS') {
|
||||
const jsonData = JSON.parse(json.response.data);
|
||||
this.setState({ activitiesJson: jsonData, loading: false });
|
||||
document.title = `Learning Dashboard - ${jsonData.name}`;
|
||||
} else {
|
||||
// When meeting is ended the sessionToken stop working, check for new cookies
|
||||
this.setDashboardParams();
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
}
|
||||
|
||||
copyPublicLink() {
|
||||
const { learningDashboardAccessToken, meetingId, ldAccessTokenCopied } = this.state;
|
||||
const { intl } = this.props;
|
||||
|
||||
let url = window.location.href.split('?')[0];
|
||||
url += `?meeting=${meetingId}&report=${learningDashboardAccessToken}&lang=${intl.locale}`;
|
||||
navigator.clipboard.writeText(url);
|
||||
if (ldAccessTokenCopied === false) {
|
||||
this.setState({ ldAccessTokenCopied: true });
|
||||
setTimeout(() => {
|
||||
this.setState({ ldAccessTokenCopied: false });
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
activitiesJson, tab, learningDashboardAccessToken, loading,
|
||||
activitiesJson, tab, sessionToken, loading,
|
||||
learningDashboardAccessToken, ldAccessTokenCopied,
|
||||
} = this.state;
|
||||
const { intl } = this.props;
|
||||
|
||||
@ -162,19 +204,60 @@ class App extends React.Component {
|
||||
}
|
||||
|
||||
function getErrorMessage() {
|
||||
if (learningDashboardAccessToken === '') {
|
||||
if (learningDashboardAccessToken === '' && sessionToken === '') {
|
||||
return intl.formatMessage({ id: 'app.learningDashboard.errors.invalidToken', defaultMessage: 'Invalid session token' });
|
||||
}
|
||||
return intl.formatMessage({ id: 'app.learningDashboard.errors.dataUnavailable', defaultMessage: 'Data is no longer available' });
|
||||
|
||||
if (activitiesJson === {} || typeof activitiesJson.name === 'undefined') {
|
||||
return intl.formatMessage({ id: 'app.learningDashboard.errors.dataUnavailable', defaultMessage: 'Data is no longer available' });
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if (loading === false && typeof activitiesJson.name === 'undefined') return <ErrorMessage message={getErrorMessage()} />;
|
||||
if (loading === false && getErrorMessage() !== '') return <ErrorMessage message={getErrorMessage()} />;
|
||||
|
||||
return (
|
||||
<div className="mx-10">
|
||||
<div className="flex items-start justify-between pb-3">
|
||||
<h1 className="mt-3 text-2xl font-semibold whitespace-nowrap inline-block">
|
||||
<FormattedMessage id="app.learningDashboard.dashboardTitle" defaultMessage="Learning Dashboard" />
|
||||
|
||||
{
|
||||
learningDashboardAccessToken !== ''
|
||||
? (
|
||||
<button type="button" onClick={() => { this.copyPublicLink(); }} className="text-sm font-medium text-blue-500 ease-out">
|
||||
(
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4 inline"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<FormattedMessage id="app.learningDashboard.shareButton" defaultMessage="Share with others" />
|
||||
)
|
||||
</button>
|
||||
)
|
||||
: null
|
||||
}
|
||||
{
|
||||
ldAccessTokenCopied === true
|
||||
? (
|
||||
<span className="text-xs text-gray-500 font-normal ml-2">
|
||||
<FormattedMessage id="app.learningDashboard.linkCopied" defaultMessage="Link successfully copied!" />
|
||||
</span>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<br />
|
||||
<span className="text-sm font-medium">{activitiesJson.name || ''}</span>
|
||||
</h1>
|
||||
|
@ -60,7 +60,7 @@ class Dashboard extends React.Component {
|
||||
setRtl() {
|
||||
const { intlLocale } = this.state;
|
||||
|
||||
if (RTL_LANGUAGES.includes(intlLocale)) {
|
||||
if (RTL_LANGUAGES.includes(intlLocale.substring(0, 2))) {
|
||||
document.body.parentNode.setAttribute('dir', 'rtl');
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
BIGBLUEBUTTON_RELEASE=2.4-rc-2
|
||||
BIGBLUEBUTTON_RELEASE=2.4-rc-3
|
||||
|
@ -178,13 +178,30 @@
|
||||
}
|
||||
|
||||
.icon-bbb-volume_off:before {
|
||||
content: "\e947";
|
||||
content: "\e95f";
|
||||
}
|
||||
|
||||
.icon-bbb-volume_up:before {
|
||||
content: "\e947";
|
||||
}
|
||||
|
||||
.icon-bbb-volume_level_1:before {
|
||||
content: "\e960";
|
||||
}
|
||||
|
||||
.icon-bbb-volume_level_2:before {
|
||||
content: "\e961";
|
||||
}
|
||||
|
||||
.icon-bbb-volume_level_3:before {
|
||||
content: "\e962";
|
||||
}
|
||||
|
||||
.icon-bbb-no_audio:before {
|
||||
content: "\e963";
|
||||
}
|
||||
|
||||
|
||||
/* Aliases for emoji status */
|
||||
.icon-bbb-time:before {
|
||||
content: "\e908";
|
||||
|
@ -23,9 +23,18 @@ export default function handleMeetingEnd({ header, body }) {
|
||||
}
|
||||
};
|
||||
|
||||
Meetings.update({ meetingId },
|
||||
{ $set: { meetingEnded: true, meetingEndedBy: userId, meetingEndedReason: reason } },
|
||||
(err, num) => { cb(err, num, 'Meeting'); });
|
||||
Meetings.find({ meetingId }).forEach((doc) => {
|
||||
Meetings.update({ meetingId },
|
||||
{
|
||||
$set: {
|
||||
meetingEnded: true,
|
||||
meetingEndedBy: userId,
|
||||
meetingEndedReason: reason,
|
||||
learningDashboardAccessToken: doc.password.learningDashboardAccessToken,
|
||||
},
|
||||
},
|
||||
(err, num) => { cb(err, num, 'Meeting'); });
|
||||
});
|
||||
|
||||
Breakouts.update({ parentMeetingId: meetingId },
|
||||
{ $set: { meetingEnded: true } },
|
||||
|
@ -56,10 +56,8 @@ function meetings() {
|
||||
},
|
||||
};
|
||||
|
||||
if (User.role === ROLE_MODERATOR) {
|
||||
delete options.fields.password;
|
||||
options.fields['password.viewerPass'] = false;
|
||||
options.fields['password.moderatorPass'] = false;
|
||||
if (User.role !== ROLE_MODERATOR) {
|
||||
options.fields.learningDashboardAccessToken = false;
|
||||
}
|
||||
|
||||
return Meetings.find(selector, options);
|
||||
|
@ -65,6 +65,8 @@ const currentParameters = [
|
||||
'bbb_hide_presentation',
|
||||
'bbb_show_participants_on_login',
|
||||
'bbb_show_public_chat_on_login',
|
||||
'bbb_hide_actions_bar',
|
||||
'bbb_hide_nav_bar',
|
||||
// OUTSIDE COMMANDS
|
||||
'bbb_outside_toggle_self_voice',
|
||||
'bbb_outside_toggle_recording',
|
||||
|
@ -323,30 +323,6 @@ WebApp.connectHandlers.use('/guestWait', (req, res) => {
|
||||
res.end(guestWaitHtml);
|
||||
});
|
||||
|
||||
// WASM endpoint to be used to fetch the .wasm models for camera effects
|
||||
// (blur, virtual background).
|
||||
// See: /imports/ui/services/virtual-backgrounds/
|
||||
WebApp.connectHandlers.use('/wasm', (req, res) => {
|
||||
const pathname = req._parsedUrl.pathname;
|
||||
let file = "";
|
||||
let hasError = false;
|
||||
try {
|
||||
file = Assets.getBinary(pathname.substr(1, pathname.length-1));
|
||||
} catch (error) {
|
||||
hasError = true;
|
||||
Logger.warn(`Could not find WASM file: ${error}`);
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'application/wasm');
|
||||
if (hasError) {
|
||||
res.writeHead(404);
|
||||
} else {
|
||||
res.writeHead(200);
|
||||
}
|
||||
res.end(file);
|
||||
});
|
||||
|
||||
|
||||
export const eventEmitter = Redis.emitter;
|
||||
|
||||
export const redisPubSub = Redis;
|
||||
|
@ -36,6 +36,7 @@ class ActionsBar extends PureComponent {
|
||||
shortcuts,
|
||||
layoutContextDispatch,
|
||||
actionsBarStyle,
|
||||
isOldMinimizeButtonEnabled,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -81,14 +82,19 @@ class ActionsBar extends PureComponent {
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
<PresentationOptionsContainer
|
||||
isLayoutSwapped={isLayoutSwapped}
|
||||
toggleSwapLayout={toggleSwapLayout}
|
||||
layoutContextDispatch={layoutContextDispatch}
|
||||
hasPresentation={isThereCurrentPresentation}
|
||||
hasExternalVideo={isSharingVideo}
|
||||
hasScreenshare={hasScreenshare}
|
||||
/>
|
||||
{!isOldMinimizeButtonEnabled ||
|
||||
(isOldMinimizeButtonEnabled && isLayoutSwapped && !isPresentationDisabled)
|
||||
? (
|
||||
<PresentationOptionsContainer
|
||||
isLayoutSwapped={isLayoutSwapped}
|
||||
toggleSwapLayout={toggleSwapLayout}
|
||||
layoutContextDispatch={layoutContextDispatch}
|
||||
hasPresentation={isThereCurrentPresentation}
|
||||
hasExternalVideo={isSharingVideo}
|
||||
hasScreenshare={hasScreenshare}
|
||||
/>
|
||||
)
|
||||
: null}
|
||||
{isRaiseHandButtonEnabled
|
||||
? (
|
||||
<Button
|
||||
|
@ -17,6 +17,7 @@ import { isVideoBroadcasting } from '/imports/ui/components/screenshare/service'
|
||||
|
||||
import MediaService, {
|
||||
getSwapLayout,
|
||||
shouldEnableSwapLayout,
|
||||
} from '../media/service';
|
||||
|
||||
const ActionsBarContainer = (props) => {
|
||||
@ -45,13 +46,14 @@ const POLLING_ENABLED = Meteor.settings.public.poll.enabled;
|
||||
const PRESENTATION_DISABLED = Meteor.settings.public.layout.hidePresentation;
|
||||
const SELECT_RANDOM_USER_ENABLED = Meteor.settings.public.selectRandomUser.enabled;
|
||||
const RAISE_HAND_BUTTON_ENABLED = Meteor.settings.public.app.raiseHandActionButton.enabled;
|
||||
const OLD_MINIMIZE_BUTTON_ENABLED = Meteor.settings.public.presentation.oldMinimizeButton;
|
||||
|
||||
export default withTracker(() => ({
|
||||
amIPresenter: Service.amIPresenter(),
|
||||
amIModerator: Service.amIModerator(),
|
||||
stopExternalVideoShare: ExternalVideoService.stopWatching,
|
||||
enableVideo: getFromUserSettings('bbb_enable_video', Meteor.settings.public.kurento.enableVideo),
|
||||
isLayoutSwapped: getSwapLayout(),
|
||||
isLayoutSwapped: getSwapLayout()&& shouldEnableSwapLayout(),
|
||||
toggleSwapLayout: MediaService.toggleSwapLayout,
|
||||
handleTakePresenter: Service.takePresenterRole,
|
||||
currentSlidHasContent: PresentationService.currentSlidHasContent(),
|
||||
@ -64,6 +66,7 @@ export default withTracker(() => ({
|
||||
isPresentationDisabled: PRESENTATION_DISABLED,
|
||||
isSelectRandomUserEnabled: SELECT_RANDOM_USER_ENABLED,
|
||||
isRaiseHandButtonEnabled: RAISE_HAND_BUTTON_ENABLED,
|
||||
isOldMinimizeButtonEnabled: OLD_MINIMIZE_BUTTON_ENABLED,
|
||||
isThereCurrentPresentation: Presentations.findOne({ meetingId: Auth.meetingID, current: true },
|
||||
{ fields: {} }),
|
||||
allowExternalVideo: Meteor.settings.public.externalVideoPlayer.enabled,
|
||||
|
@ -340,37 +340,6 @@ class App extends Component {
|
||||
&& (isPhone || isLayeredView.matches);
|
||||
}
|
||||
|
||||
renderNavBar() {
|
||||
const { navbar, isLargeFont } = this.props;
|
||||
|
||||
if (!navbar) return null;
|
||||
|
||||
const realNavbarHeight = isLargeFont ? LARGE_NAVBAR_HEIGHT : NAVBAR_HEIGHT;
|
||||
|
||||
return (
|
||||
<header
|
||||
className={styles.navbar}
|
||||
style={{
|
||||
height: realNavbarHeight,
|
||||
}}
|
||||
>
|
||||
{navbar}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
renderSidebar() {
|
||||
const { sidebar } = this.props;
|
||||
|
||||
if (!sidebar) return null;
|
||||
|
||||
return (
|
||||
<aside className={styles.sidebar}>
|
||||
{sidebar}
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
renderCaptions() {
|
||||
const {
|
||||
captions,
|
||||
@ -401,9 +370,10 @@ class App extends Component {
|
||||
actionsbar,
|
||||
intl,
|
||||
actionsBarStyle,
|
||||
hideActionsBar,
|
||||
} = this.props;
|
||||
|
||||
if (!actionsbar) return null;
|
||||
if (!actionsbar || hideActionsBar) return null;
|
||||
|
||||
return (
|
||||
<section
|
||||
|
@ -211,6 +211,7 @@ export default injectIntl(withModalMounter(withTracker(({ intl, baseControls })
|
||||
Meteor.settings.public.presentation.restoreOnUpdate,
|
||||
),
|
||||
hidePresentation: getFromUserSettings('bbb_hide_presentation', LAYOUT_CONFIG.hidePresentation),
|
||||
hideActionsBar: getFromUserSettings('bbb_hide_actions_bar', false),
|
||||
};
|
||||
})(AppContainer)));
|
||||
|
||||
|
@ -82,7 +82,7 @@ class AudioControls extends PureComponent {
|
||||
data-test="joinAudio"
|
||||
color="default"
|
||||
ghost
|
||||
icon="audio_off"
|
||||
icon="no_audio"
|
||||
size="lg"
|
||||
circle
|
||||
accessKey={shortcuts.joinaudio}
|
||||
@ -108,12 +108,12 @@ class AudioControls extends PureComponent {
|
||||
shortcuts,
|
||||
} = this.props;
|
||||
|
||||
let joinIcon = 'audio_off';
|
||||
let joinIcon = 'no_audio';
|
||||
if (inAudio) {
|
||||
if (listenOnly) {
|
||||
joinIcon = 'listen';
|
||||
} else {
|
||||
joinIcon = 'audio_on';
|
||||
joinIcon = 'volume_level_2';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ class InputStreamLiveSelector extends Component {
|
||||
data-test="leaveAudio"
|
||||
hideLabel
|
||||
color="primary"
|
||||
icon={isListenOnly ? 'listen' : 'audio_on'}
|
||||
icon={isListenOnly ? 'listen' : 'volume_level_2'}
|
||||
size="lg"
|
||||
circle
|
||||
onClick={(e) => {
|
||||
@ -302,6 +302,7 @@ class InputStreamLiveSelector extends Component {
|
||||
}}
|
||||
/>
|
||||
<ButtonEmoji
|
||||
className={styles.audioDropdown}
|
||||
emoji="device_list_selector"
|
||||
label={intl.formatMessage(intlMessages.changeAudioDevice)}
|
||||
hideLabel
|
||||
|
@ -101,3 +101,12 @@
|
||||
.selectedDevice {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.audioDropdown {
|
||||
span {
|
||||
i {
|
||||
width: 0px !important;
|
||||
bottom: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ export default lockContextContainer(withModalMounter(injectIntl(withTracker(({ m
|
||||
|
||||
if (userMic && !Service.isMuted()) {
|
||||
Service.toggleMuteMicrophone();
|
||||
notify(intl.formatMessage(intlMessages.reconectingAsListener), 'info', 'audio_on');
|
||||
notify(intl.formatMessage(intlMessages.reconectingAsListener), 'info', 'volume_level_2');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ const propTypes = {
|
||||
tabIndex: PropTypes.number,
|
||||
|
||||
hideLabel: PropTypes.bool,
|
||||
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@ -33,11 +35,13 @@ const defaultProps = {
|
||||
tabIndex: -1,
|
||||
hideLabel: false,
|
||||
onClick: null,
|
||||
className: '',
|
||||
};
|
||||
|
||||
const ButtonEmoji = (props) => {
|
||||
const {
|
||||
hideLabel,
|
||||
className,
|
||||
...newProps
|
||||
} = props;
|
||||
|
||||
@ -62,7 +66,7 @@ const ButtonEmoji = (props) => {
|
||||
type="button"
|
||||
tabIndex={tabIndex}
|
||||
{...newProps}
|
||||
className={styles.emojiButton}
|
||||
className={[styles.emojiButton, className].join(' ')}
|
||||
aria-label={label}
|
||||
onClick={onClick}
|
||||
>
|
||||
|
@ -20,23 +20,45 @@ const isModerator = () => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const getLearningDashboardAccessToken = () => ((
|
||||
const isLearningDashboardEnabled = () => (((
|
||||
Meetings.findOne(
|
||||
{ meetingId: Auth.meetingID },
|
||||
{
|
||||
fields: { 'password.learningDashboardAccessToken': 1 },
|
||||
fields: { 'meetingProp.learningDashboardEnabled': 1 },
|
||||
},
|
||||
) || {}).password || {}).learningDashboardAccessToken || null;
|
||||
) || {}).meetingProp || {}).learningDashboardEnabled || false);
|
||||
|
||||
const getLearningDashboardAccessToken = () => ((
|
||||
Meetings.findOne(
|
||||
{ meetingId: Auth.meetingID, learningDashboardAccessToken: { $exists: true } },
|
||||
{
|
||||
fields: { learningDashboardAccessToken: 1 },
|
||||
},
|
||||
) || {}).learningDashboardAccessToken || null);
|
||||
|
||||
const setLearningDashboardCookie = () => {
|
||||
const learningDashboardAccessToken = getLearningDashboardAccessToken();
|
||||
if (learningDashboardAccessToken !== null) {
|
||||
const cookieExpiresDate = new Date();
|
||||
cookieExpiresDate.setTime(cookieExpiresDate.getTime() + (3600000 * 24 * 30)); // keep cookie 30d
|
||||
document.cookie = `learningDashboardAccessToken-${Auth.meetingID}=${getLearningDashboardAccessToken()}; expires=${cookieExpiresDate.toGMTString()}; path=/`;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const openLearningDashboardUrl = (lang) => {
|
||||
const cookieExpiresDate = new Date();
|
||||
cookieExpiresDate.setTime(cookieExpiresDate.getTime() + (3600000 * 24 * 30)); // keep cookie 30d
|
||||
document.cookie = `learningDashboardAccessToken-${Auth.meetingID}=${getLearningDashboardAccessToken()}; expires=${cookieExpiresDate.toGMTString()}; path=/`;
|
||||
window.open(`/learning-dashboard/?meeting=${Auth.meetingID}&lang=${lang}`, '_blank');
|
||||
if (getLearningDashboardAccessToken() && setLearningDashboardCookie()) {
|
||||
window.open(`/learning-dashboard/?meeting=${Auth.meetingID}&lang=${lang}`, '_blank');
|
||||
} else {
|
||||
window.open(`/learning-dashboard/?meeting=${Auth.meetingID}&sessionToken=${Auth.sessionToken}&lang=${lang}`, '_blank');
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
isModerator,
|
||||
isLearningDashboardEnabled,
|
||||
getLearningDashboardAccessToken,
|
||||
setLearningDashboardCookie,
|
||||
openLearningDashboardUrl,
|
||||
};
|
||||
|
@ -9,6 +9,7 @@ import { ACTIONS } from '../layout/enums';
|
||||
|
||||
const LAYOUT_CONFIG = Meteor.settings.public.layout;
|
||||
const KURENTO_CONFIG = Meteor.settings.public.kurento;
|
||||
const PRESENTATION_CONFIG = Meteor.settings.public.presentation;
|
||||
|
||||
const getPresentationInfo = () => {
|
||||
const currentPresentation = Presentations.findOne({
|
||||
@ -72,6 +73,13 @@ const toggleSwapLayout = (layoutContextDispatch) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const shouldEnableSwapLayout = () => {
|
||||
if (!PRESENTATION_CONFIG.oldMinimizeButton) {
|
||||
return true;
|
||||
}
|
||||
return !shouldShowScreenshare() && !shouldShowExternalVideo();
|
||||
}
|
||||
|
||||
export const getSwapLayout = () => {
|
||||
swapLayout.tracker.depend();
|
||||
return swapLayout.value;
|
||||
@ -86,6 +94,7 @@ export default {
|
||||
isUserPresenter,
|
||||
isVideoBroadcasting,
|
||||
toggleSwapLayout,
|
||||
shouldEnableSwapLayout,
|
||||
getSwapLayout,
|
||||
setSwapLayout,
|
||||
};
|
||||
|
@ -266,7 +266,9 @@ class MeetingEnded extends PureComponent {
|
||||
<div>
|
||||
{
|
||||
LearningDashboardService.isModerator()
|
||||
&& LearningDashboardService.getLearningDashboardAccessToken() != null
|
||||
&& LearningDashboardService.isLearningDashboardEnabled() === true
|
||||
// Always set cookie in case Dashboard is already opened
|
||||
&& LearningDashboardService.setLearningDashboardCookie() === true
|
||||
? (
|
||||
<div className={styles.text}>
|
||||
<Button
|
||||
|
@ -8,6 +8,7 @@
|
||||
margin-right: 1.65rem;
|
||||
margin-left: .5rem;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
padding: .1rem 0;
|
||||
|
||||
[dir="rtl"] & {
|
||||
|
@ -54,6 +54,10 @@ const NavBarContainer = ({ children, ...props }) => {
|
||||
const currentUser = users[Auth.meetingID][Auth.userID];
|
||||
const amIModerator = currentUser.role === ROLE_MODERATOR;
|
||||
|
||||
const hideNavBar = getFromUserSettings('bbb_hide_nav_bar', false);
|
||||
|
||||
if (hideNavBar) return null;
|
||||
|
||||
return (
|
||||
<NavBar
|
||||
{...{
|
||||
|
@ -493,7 +493,7 @@ class Poll extends Component {
|
||||
)}
|
||||
</div>
|
||||
<div data-test="responseTypes">
|
||||
<h4>{intl.formatMessage(intlMessages.responseTypesLabel)}</h4>
|
||||
<h4 className={styles.sectionHeading}>{intl.formatMessage(intlMessages.responseTypesLabel)}</h4>
|
||||
<div className={styles.responseType}>
|
||||
<Button
|
||||
label={intl.formatMessage(intlMessages.tf)}
|
||||
@ -573,11 +573,11 @@ class Poll extends Component {
|
||||
{type
|
||||
&& (
|
||||
<div data-test="responseChoices">
|
||||
<h4>{intl.formatMessage(intlMessages.responseChoices)}</h4>
|
||||
<h4 className={styles.sectionHeading}>{intl.formatMessage(intlMessages.responseChoices)}</h4>
|
||||
{
|
||||
type === pollTypes.Response
|
||||
&& (
|
||||
<div>
|
||||
<div className={styles.pollParagraph}>
|
||||
<span>{intl.formatMessage(intlMessages.typedResponseDesc)}</span>
|
||||
</div>
|
||||
)
|
||||
@ -607,10 +607,9 @@ class Poll extends Component {
|
||||
)}
|
||||
<div className={styles.row}>
|
||||
<div className={styles.col} aria-hidden="true">
|
||||
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
|
||||
<label className={styles.label}>
|
||||
<h4 className={styles.sectionHeading}>
|
||||
{intl.formatMessage(intlMessages.secretPollLabel)}
|
||||
</label>
|
||||
</h4>
|
||||
</div>
|
||||
<div className={styles.col}>
|
||||
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
|
||||
@ -628,7 +627,7 @@ class Poll extends Component {
|
||||
</div>
|
||||
{secretPoll
|
||||
&& (
|
||||
<div>
|
||||
<div className={styles.pollParagraph}>
|
||||
{ intl.formatMessage(intlMessages.isSecretPollLabel) }
|
||||
</div>
|
||||
)}
|
||||
@ -697,7 +696,7 @@ class Poll extends Component {
|
||||
const { intl } = this.props;
|
||||
return (
|
||||
<div className={styles.noSlidePanelContainer}>
|
||||
<h4>{intl.formatMessage(intlMessages.noPresentationSelected)}</h4>
|
||||
<h4 className={styles.sectionHeading}>{intl.formatMessage(intlMessages.noPresentationSelected)}</h4>
|
||||
<Button
|
||||
label={intl.formatMessage(intlMessages.clickHereToSelect)}
|
||||
color="primary"
|
||||
|
@ -403,7 +403,6 @@
|
||||
position: relative;
|
||||
flex-flow: column;
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
@ -423,3 +422,13 @@
|
||||
margin: 0 0 0 var(--sm-padding-x);
|
||||
}
|
||||
}
|
||||
|
||||
.sectionHeading {
|
||||
margin-top: 0;
|
||||
font-weight: 600;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
|
||||
.pollParagraph {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import PresentationOverlayContainer from './presentation-overlay/container';
|
||||
import Slide from './slide/component';
|
||||
import { styles } from './styles.scss';
|
||||
import toastStyles from '/imports/ui/components/toast/styles';
|
||||
import MediaService, { shouldEnableSwapLayout } from '../media/service';
|
||||
import PresentationCloseButton from './presentation-close-button/component';
|
||||
import DownloadPresentationButton from './download-presentation-button/component';
|
||||
import FullscreenService from '../fullscreen-button/service';
|
||||
import FullscreenButtonContainer from '../fullscreen-button/container';
|
||||
@ -49,6 +51,7 @@ const intlMessages = defineMessages({
|
||||
});
|
||||
|
||||
const ALLOW_FULLSCREEN = Meteor.settings.public.app.allowFullscreen;
|
||||
const OLD_MINIMIZE_BUTTON_ENABLED = Meteor.settings.public.presentation.oldMinimizeButton;
|
||||
|
||||
class Presentation extends PureComponent {
|
||||
constructor() {
|
||||
@ -425,6 +428,31 @@ class Presentation extends PureComponent {
|
||||
zoomSlide(currentSlide.num, podId, w, h, x, y);
|
||||
}
|
||||
|
||||
renderPresentationClose() {
|
||||
const { isFullscreen } = this.state;
|
||||
const {
|
||||
layoutType,
|
||||
fullscreenContext,
|
||||
layoutContextDispatch,
|
||||
isIphone,
|
||||
} = this.props;
|
||||
|
||||
if (!OLD_MINIMIZE_BUTTON_ENABLED
|
||||
|| !shouldEnableSwapLayout()
|
||||
|| isFullscreen
|
||||
|| fullscreenContext
|
||||
|| layoutType === LAYOUT_TYPE.PRESENTATION_FOCUS) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<PresentationCloseButton
|
||||
toggleSwapLayout={MediaService.toggleSwapLayout}
|
||||
layoutContextDispatch={layoutContextDispatch}
|
||||
isIphone={isIphone}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderOverlays(slideObj, svgDimensions, viewBoxPosition, viewBoxDimensions, physicalDimensions) {
|
||||
const {
|
||||
userIsPresenter,
|
||||
@ -562,6 +590,7 @@ class Presentation extends PureComponent {
|
||||
}}
|
||||
>
|
||||
<span id="currentSlideText" className={styles.visuallyHidden}>{slideContent}</span>
|
||||
{this.renderPresentationClose()}
|
||||
{this.renderPresentationDownload()}
|
||||
{this.renderPresentationFullscreen()}
|
||||
<svg
|
||||
|
@ -1,6 +1,9 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import MediaService, { getSwapLayout, } from '/imports/ui/components/media/service';
|
||||
import MediaService, {
|
||||
getSwapLayout,
|
||||
shouldEnableSwapLayout,
|
||||
} from '/imports/ui/components/media/service';
|
||||
import { notify } from '/imports/ui/services/notification';
|
||||
import PresentationService from './service';
|
||||
import { Slides } from '/imports/api/slides';
|
||||
@ -72,7 +75,7 @@ const fetchedpresentation = {};
|
||||
export default withTracker(({ podId }) => {
|
||||
const currentSlide = PresentationService.getCurrentSlide(podId);
|
||||
const presentationIsDownloadable = PresentationService.isPresentationDownloadable(podId);
|
||||
const layoutSwapped = getSwapLayout();
|
||||
const layoutSwapped = getSwapLayout() && shouldEnableSwapLayout();
|
||||
|
||||
let slidePosition;
|
||||
if (currentSlide) {
|
||||
|
@ -45,7 +45,7 @@ export default withTracker((params) => {
|
||||
|
||||
return {
|
||||
amIPresenter: Service.amIPresenter(),
|
||||
layoutSwapped: MediaService.getSwapLayout(),
|
||||
layoutSwapped: MediaService.getSwapLayout() && MediaService.shouldEnableSwapLayout(),
|
||||
userIsPresenter: PresentationService.isPresenter(podId),
|
||||
numberOfSlides: PresentationToolbarService.getNumberOfSlides(podId, presentationId),
|
||||
nextSlide: PresentationToolbarService.nextSlide,
|
||||
|
@ -2,7 +2,10 @@ import React from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import Users from '/imports/api/users/';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import MediaService, { getSwapLayout, } from '/imports/ui/components/media/service';
|
||||
import MediaService, {
|
||||
getSwapLayout,
|
||||
shouldEnableSwapLayout,
|
||||
} from '/imports/ui/components/media/service';
|
||||
import {
|
||||
isVideoBroadcasting,
|
||||
isGloballyBroadcasting,
|
||||
@ -46,6 +49,7 @@ export default withTracker(() => {
|
||||
isGloballyBroadcasting: isGloballyBroadcasting(),
|
||||
isPresenter: user.presenter,
|
||||
getSwapLayout,
|
||||
shouldEnableSwapLayout,
|
||||
toggleSwapLayout: MediaService.toggleSwapLayout,
|
||||
hidePresentation: getFromUserSettings('bbb_hide_presentation', LAYOUT_CONFIG.hidePresentation),
|
||||
};
|
||||
|
@ -541,7 +541,7 @@ class UserDropdown extends PureComponent {
|
||||
? (<Icon iconName={normalizeEmojiName(user.emoji)} />)
|
||||
: user.name.toLowerCase().slice(0, 2);
|
||||
|
||||
const iconVoiceOnlyUser = (<Icon iconName="audio_on" />);
|
||||
const iconVoiceOnlyUser = (<Icon iconName="volume_level_2" />);
|
||||
const userIcon = isVoiceOnly ? iconVoiceOnlyUser : iconUser;
|
||||
|
||||
return (
|
||||
|
@ -214,7 +214,7 @@ class UserOptions extends PureComponent {
|
||||
hasBreakoutRoom,
|
||||
isBreakoutEnabled,
|
||||
getUsersNotAssigned,
|
||||
learningDashboardAccessToken,
|
||||
learningDashboardEnabled,
|
||||
openLearningDashboardUrl,
|
||||
amIModerator,
|
||||
users,
|
||||
@ -326,7 +326,7 @@ class UserOptions extends PureComponent {
|
||||
});
|
||||
}
|
||||
if (amIModerator) {
|
||||
if (learningDashboardAccessToken != null) {
|
||||
if (learningDashboardEnabled === true) {
|
||||
this.menuItems.push({
|
||||
icon: 'multi_whiteboard',
|
||||
iconRight: 'popout_window',
|
||||
@ -336,7 +336,7 @@ class UserOptions extends PureComponent {
|
||||
onClick: () => { openLearningDashboardUrl(locale); },
|
||||
dividerTop: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ const UserOptionsContainer = withTracker((props) => {
|
||||
guestPolicy: WaitingUsersService.getGuestPolicy(),
|
||||
isMeteorConnected: Meteor.status().connected,
|
||||
meetingName: getMeetingName(),
|
||||
learningDashboardAccessToken: LearningDashboardService.getLearningDashboardAccessToken(),
|
||||
learningDashboardEnabled: LearningDashboardService.isLearningDashboardEnabled(),
|
||||
openLearningDashboardUrl: LearningDashboardService.openLearningDashboardUrl,
|
||||
dynamicGuestPolicy,
|
||||
};
|
||||
|
@ -2,8 +2,7 @@ import React, { useContext } from 'react';
|
||||
|
||||
import { withModalMounter } from '/imports/ui/components/modal/service';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import Settings from '/imports/ui/services/settings';
|
||||
import MediaService, { getSwapLayout, } from '/imports/ui/components/media/service';
|
||||
import MediaService, { getSwapLayout, shouldEnableSwapLayout } from '/imports/ui/components/media/service';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import breakoutService from '/imports/ui/components/breakout-room/service';
|
||||
import VideoService from '/imports/ui/components/video-provider/service';
|
||||
@ -20,7 +19,6 @@ const WebcamContainer = ({
|
||||
audioModalIsOpen,
|
||||
swapLayout,
|
||||
usersVideo,
|
||||
disableVideo,
|
||||
}) => {
|
||||
const fullscreen = layoutSelect((i) => i.fullscreen);
|
||||
const isRTL = layoutSelect((i) => i.isRTL);
|
||||
@ -36,8 +34,7 @@ const WebcamContainer = ({
|
||||
const { users } = usingUsersContext;
|
||||
const currentUser = users[Auth.meetingID][Auth.userID];
|
||||
|
||||
return !disableVideo
|
||||
&& !audioModalIsOpen
|
||||
return !audioModalIsOpen
|
||||
&& usersVideo.length > 0
|
||||
? (
|
||||
<WebcamComponent
|
||||
@ -60,8 +57,6 @@ const WebcamContainer = ({
|
||||
let userWasInBreakout = false;
|
||||
|
||||
export default withModalMounter(withTracker(() => {
|
||||
const { dataSaving } = Settings;
|
||||
const { viewParticipantsWebcams } = dataSaving;
|
||||
const { current_presentation: hasPresentation } = MediaService.getPresentationInfo();
|
||||
const data = {
|
||||
audioModalIsOpen: Session.get('audioModalIsOpen'),
|
||||
@ -95,8 +90,7 @@ export default withModalMounter(withTracker(() => {
|
||||
|
||||
const { streams: usersVideo } = VideoService.getVideoStreams();
|
||||
data.usersVideo = usersVideo;
|
||||
data.swapLayout = getSwapLayout() || !hasPresentation;
|
||||
data.disableVideo = !viewParticipantsWebcams;
|
||||
data.swapLayout = (getSwapLayout() || !hasPresentation) && shouldEnableSwapLayout();
|
||||
|
||||
if (data.swapLayout) {
|
||||
data.floatingOverlay = true;
|
||||
|
@ -6,6 +6,7 @@ import { injectIntl, defineMessages } from 'react-intl';
|
||||
import styles from './styles';
|
||||
import {
|
||||
getSwapLayout,
|
||||
shouldEnableSwapLayout,
|
||||
} from '/imports/ui/components/media/service';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
@ -72,7 +73,7 @@ class PollDrawComponent extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const isLayoutSwapped = getSwapLayout();
|
||||
const isLayoutSwapped = getSwapLayout() && shouldEnableSwapLayout();
|
||||
if (isLayoutSwapped) return;
|
||||
|
||||
this.pollInitialCalculation();
|
||||
|
@ -463,7 +463,11 @@ class AudioManager {
|
||||
}
|
||||
|
||||
if (!this.error && !this.isEchoTest) {
|
||||
this.notify(this.intl.formatMessage(this.messages.info.LEFT_AUDIO), false, 'audio_off');
|
||||
this.notify(
|
||||
this.intl.formatMessage(this.messages.info.LEFT_AUDIO),
|
||||
false,
|
||||
'no_audio'
|
||||
);
|
||||
}
|
||||
if (!this.isEchoTest) {
|
||||
this.playHangUpSound();
|
||||
|
@ -556,6 +556,7 @@ public:
|
||||
allowDownloadable: true
|
||||
panZoomThrottle: 32
|
||||
restoreOnUpdate: false
|
||||
oldMinimizeButton: false
|
||||
uploadEndpoint: '/bigbluebutton/presentation/upload'
|
||||
uploadValidMimeTypes:
|
||||
- extension: .pdf
|
||||
|
Binary file not shown.
@ -266,9 +266,9 @@
|
||||
"app.poll.showRespDesc": "يعرض تكوين الاستجابة",
|
||||
"app.poll.addRespDesc": "يضيف مدخلات استجابة التصويت",
|
||||
"app.poll.deleteRespDesc": "يزيل الخيار {0}",
|
||||
"app.poll.t": "صواب",
|
||||
"app.poll.t": "صحيح",
|
||||
"app.poll.f": "خطأ",
|
||||
"app.poll.tf": "صواب / خطأ",
|
||||
"app.poll.tf": "صحيح / خطأ",
|
||||
"app.poll.y": "نعم",
|
||||
"app.poll.n": "لا",
|
||||
"app.poll.abstention": "امتناع",
|
||||
@ -277,7 +277,7 @@
|
||||
"app.poll.a3": "أ / ب / ج",
|
||||
"app.poll.a4": "أ / ب / ج / د",
|
||||
"app.poll.a5": "أ / ب / ج / د / هـ",
|
||||
"app.poll.answer.true": "صواب",
|
||||
"app.poll.answer.true": "صحيح",
|
||||
"app.poll.answer.false": "خطأ",
|
||||
"app.poll.answer.yes": "نعم",
|
||||
"app.poll.answer.no": "لا",
|
||||
@ -411,6 +411,8 @@
|
||||
"app.switch.offLabel": "إيقاف",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "اختر لكتم صوت المستخدم",
|
||||
"app.talkingIndicator.isTalking" : "{0} يتحدث",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+ يتحدثون",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+ كانوا يتحدثون",
|
||||
"app.talkingIndicator.wasTalking" : "{0} توقف عن الكلام",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "الاجراءات",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "إدارة العروض",
|
||||
@ -816,6 +818,7 @@
|
||||
"app.createBreakoutRoom.title": "الغرف الجانبية",
|
||||
"app.createBreakoutRoom.ariaTitle": "إخفاء الغرف الجانبية",
|
||||
"app.createBreakoutRoom.breakoutRoomLabel": "غرفة جانبية {0}",
|
||||
"app.createBreakoutRoom.askToJoin": "اطلب الانضمام",
|
||||
"app.createBreakoutRoom.generatingURL": "إنشاء الرابط",
|
||||
"app.createBreakoutRoom.generatingURLMessage": "نحن نقوم بإنشاء رابط خاص بالغرفة الجانبية المختارة. قد يستغرق الأمر بضع ثوان ...",
|
||||
"app.createBreakoutRoom.duration": "المدة {0}",
|
||||
@ -909,6 +912,8 @@
|
||||
"playback.player.video.wrapper.aria": "مساحة الفيديو",
|
||||
"app.learningDashboard.dashboardTitle": "لوحة التعلم",
|
||||
"app.learningDashboard.user": "مستخدم",
|
||||
"app.learningDashboard.shareButton": "شارك مع الآخرين",
|
||||
"app.learningDashboard.shareLinkCopied": "تم نسخ الرابط بنجاح",
|
||||
"app.learningDashboard.indicators.meetingStatusEnded": "انتهت",
|
||||
"app.learningDashboard.indicators.meetingStatusActive": "فعًال",
|
||||
"app.learningDashboard.indicators.usersOnline": "المستخدمين النشطين",
|
||||
|
@ -411,6 +411,8 @@
|
||||
"app.switch.offLabel": "AUS",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "Auswählen, um Teilnehmer stummzuschalten",
|
||||
"app.talkingIndicator.isTalking" : "{0} spricht",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+ sprechen",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+ sprachen",
|
||||
"app.talkingIndicator.wasTalking" : "{0} spricht nicht mehr",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "Aktionen",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "Präsentationen verwalten",
|
||||
@ -590,7 +592,7 @@
|
||||
"app.guest.missingMeeting": "Konferenz existiert nicht.",
|
||||
"app.guest.meetingEnded": "Konferenz beendet.",
|
||||
"app.guest.guestWait": "Bitte warten Sie, bis ein Moderator Ihre Teilnahme an der Konferenz freigibt.",
|
||||
"app.guest.guestDeny": "Gast wurde die Teilnahme an der Konferenz abgelehnt.",
|
||||
"app.guest.guestDeny": "Der Moderator hat die Teilnahme an der Konferenz abgelehnt.",
|
||||
"app.guest.seatWait": "Gast wartet auf die Teilnahme an der Konferenz.",
|
||||
"app.guest.allow": "Gast zugelassen und zur Konferenz weitergeleitet.",
|
||||
"app.userList.guest.waitingUsers": "Wartende Teilnehmer",
|
||||
@ -601,7 +603,7 @@
|
||||
"app.userList.guest.allowEveryone": "Alle erlauben",
|
||||
"app.userList.guest.denyEveryone": "Alle verweigern",
|
||||
"app.userList.guest.pendingUsers": "{0} unbearbeitete Teilnehmer",
|
||||
"app.userList.guest.pendingGuestUsers": "{0} unbearbeitete Gäste",
|
||||
"app.userList.guest.pendingGuestUsers": "{0} wartende Gäste",
|
||||
"app.userList.guest.pendingGuestAlert": "Ist der Konferenz beigetreten und wartet auf Ihre Teilnahmeerlaubnis",
|
||||
"app.userList.guest.rememberChoice": "Auswahl für die Zukunft speichern",
|
||||
"app.userList.guest.emptyMessage": "Momentan keine Nachricht vorhanden",
|
||||
@ -816,7 +818,7 @@
|
||||
"app.createBreakoutRoom.title": "Gruppenräume",
|
||||
"app.createBreakoutRoom.ariaTitle": "Gruppenräume verbergen",
|
||||
"app.createBreakoutRoom.breakoutRoomLabel": "Gruppenräume {0}",
|
||||
"app.createBreakoutRoom.askToJoin": "Beitreten auffordern",
|
||||
"app.createBreakoutRoom.askToJoin": "Raum beitreten",
|
||||
"app.createBreakoutRoom.generatingURL": "Erzeuge URL",
|
||||
"app.createBreakoutRoom.generatingURLMessage": "Wir generieren eine Teilnahme-URL für den ausgewählten Gruppenraum. Das kann ein paar Sekunden dauern...",
|
||||
"app.createBreakoutRoom.duration": "Dauer {0}",
|
||||
@ -910,6 +912,8 @@
|
||||
"playback.player.video.wrapper.aria": "Webcambereich",
|
||||
"app.learningDashboard.dashboardTitle": "Lern-Dashboard",
|
||||
"app.learningDashboard.user": "Teilnehmer",
|
||||
"app.learningDashboard.shareButton": "Mit anderen teilen",
|
||||
"app.learningDashboard.shareLinkCopied": "Link erfolgreich kopiert",
|
||||
"app.learningDashboard.indicators.meetingStatusEnded": "Beendet",
|
||||
"app.learningDashboard.indicators.meetingStatusActive": "Aktiv",
|
||||
"app.learningDashboard.indicators.usersOnline": "Aktive Teilnehmer",
|
||||
|
@ -913,6 +913,8 @@
|
||||
"playback.player.video.wrapper.aria": "Video area",
|
||||
"app.learningDashboard.dashboardTitle": "Learning Dashboard",
|
||||
"app.learningDashboard.user": "User",
|
||||
"app.learningDashboard.shareButton": "Share with others",
|
||||
"app.learningDashboard.shareLinkCopied": "Link successfully copied!",
|
||||
"app.learningDashboard.indicators.meetingStatusEnded": "Ended",
|
||||
"app.learningDashboard.indicators.meetingStatusActive": "Active",
|
||||
"app.learningDashboard.indicators.usersOnline": "Active Users",
|
||||
|
@ -411,6 +411,8 @@
|
||||
"app.switch.offLabel": "VÄLJAS",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "Vali vaigistamiseks kasutaja",
|
||||
"app.talkingIndicator.isTalking" : "{0} räägib",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+ räägivad",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+ rääkisid",
|
||||
"app.talkingIndicator.wasTalking" : "{0} lõpetas rääkimise",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "Tegevused",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "Halda esitlusi",
|
||||
|
@ -25,6 +25,8 @@
|
||||
"app.chat.multi.typing": "چند کاربر در حال نوشتن هستند",
|
||||
"app.chat.one.typing": "{0} در حال نوشتن است",
|
||||
"app.chat.two.typing": "{0} و {1} در حال نوشتن هستند",
|
||||
"app.chat.copySuccess": "محتوای گفتگو کپی شد",
|
||||
"app.chat.copyErr": "کپی محتوای گفتگو با خطا مواجه شد!",
|
||||
"app.captions.label": "عناوین",
|
||||
"app.captions.menu.close": "بستن",
|
||||
"app.captions.menu.start": "شروع",
|
||||
@ -51,6 +53,7 @@
|
||||
"app.captions.pad.dictationOffDesc": "غیر فعال کردن امکان تشخیص صوت",
|
||||
"app.captions.pad.speechRecognitionStop": "به دلیل مشکلات مرورگر یا ایجاد وقفه، تبدیل گفتار متوقف شده است.",
|
||||
"app.textInput.sendLabel": "ارسال",
|
||||
"app.title.defaultViewLabel": "نمای پیشفرض ارائه",
|
||||
"app.note.title": "یادداشتهای اشتراکی",
|
||||
"app.note.label": "یادداشت",
|
||||
"app.note.hideNoteLabel": "پنهان کردن یادداشت",
|
||||
@ -145,6 +148,8 @@
|
||||
"app.meeting.meetingTimeRemaining": "زمان باقی مانده از جلسه: {0}",
|
||||
"app.meeting.meetingTimeHasEnded": "زمان جلسه به اتمام رسید. جلسه به زودی بسته خواهد شد",
|
||||
"app.meeting.endedByUserMessage": "این جلسه توسط {0} به پایان رسید",
|
||||
"app.meeting.endedByNoModeratorMessageSingular": "جلسه به دلیل عدم حضور یک مدیر پس از یک دقیقه تمام شد",
|
||||
"app.meeting.endedByNoModeratorMessagePlural": "جلسه به دلیل عدم حضور یک میانجی پس از {0} دقیقه تمام شد.",
|
||||
"app.meeting.endedMessage": "شما در حال انتقال به صفحه اصلی هستید",
|
||||
"app.meeting.alertMeetingEndsUnderMinutesSingular": "جلسه تا یک دقیقه دیگر به پایان میرسد.",
|
||||
"app.meeting.alertMeetingEndsUnderMinutesPlural": "جلسه تا {0} دقیقه دیگر به پایان میرسد.",
|
||||
@ -181,6 +186,7 @@
|
||||
"app.presentation.presentationToolbar.fitToWidth": "اندازه تصویر را متناسب با عرض ارائه کن",
|
||||
"app.presentation.presentationToolbar.fitToPage": "اندازه تصویر را متناسب با عرض صفحه کن",
|
||||
"app.presentation.presentationToolbar.goToSlide": "اسلاید {0}",
|
||||
"app.presentation.placeholder": "در انتظار بارگذاری یک ارائه",
|
||||
"app.presentationUploder.title": "ارائه",
|
||||
"app.presentationUploder.message": "به عنوان یک ارائه دهنده شما قادرید انواع فایل های مجموعه آفیس و یا فایل PDF را بارگذاری نمایید؛ پیشنهاد ما برای رسیدن به بهترین نتایج، استفاده از فایل PDF میباشد. لطفا از انتخاب بودن یک ارائه توسط گزینه سمت راست اطمینان حاصل کنید.",
|
||||
"app.presentationUploder.uploadLabel": "بارگذاری",
|
||||
@ -227,6 +233,7 @@
|
||||
"app.presentationUploder.itemPlural" : "آیتمها",
|
||||
"app.presentationUploder.clearErrors": "پاک کردن خطاها",
|
||||
"app.presentationUploder.clearErrorsDesc": "پاک کردن بارگذاریهای ناموفق ارائه",
|
||||
"app.presentationUploder.uploadViewTitle": "بارگذاری ارائه ",
|
||||
"app.poll.pollPaneTitle": "نظرسنجی",
|
||||
"app.poll.quickPollTitle": "نظرسنجی سریع",
|
||||
"app.poll.hidePollDesc": "پنهانسازی منوی نظرسنجی",
|
||||
@ -242,6 +249,8 @@
|
||||
"app.poll.customPlaceholder": "افزودن گزینه نظرسنجی",
|
||||
"app.poll.noPresentationSelected": "هیچ ارائهای انتخاب نشده است! لطفا یکی را انتخاب کنید.",
|
||||
"app.poll.clickHereToSelect": "برای انتخاب اینجا را کلیک کن",
|
||||
"app.poll.question.label" : "سوالتان را بنویسید ...",
|
||||
"app.poll.optionalQuestion.label" : "سوالتان را بنویسید (اختیاری) ...",
|
||||
"app.poll.userResponse.label" : "پاسخ کاربر",
|
||||
"app.poll.responseTypes.label" : "نوع پاسخها",
|
||||
"app.poll.optionDelete.label" : "حذف",
|
||||
@ -250,7 +259,13 @@
|
||||
"app.poll.addItem.label" : "اضافه کردن آیتم",
|
||||
"app.poll.start.label" : "آغاز نظرسنجی",
|
||||
"app.poll.secretPoll.label" : "رأیگیری ناشناس",
|
||||
"app.poll.secretPoll.isSecretLabel": "این نظرسنجی ناشناس است - شما قادر نخواهید بود پاسخهای فردی را ببینید.",
|
||||
"app.poll.questionErr": "ارائه یک سوال الزامی است.",
|
||||
"app.poll.optionErr": "یک گزینه نظرسنجی وارد کنید",
|
||||
"app.poll.startPollDesc": "آغاز رایگیری",
|
||||
"app.poll.showRespDesc": "نمایش پاسخ پیکربندی",
|
||||
"app.poll.addRespDesc": "اضافه کردن ورودی پاسخ نظر سنجی",
|
||||
"app.poll.deleteRespDesc": "حذف گزینه {0}",
|
||||
"app.poll.t": "درست",
|
||||
"app.poll.f": "نادرست",
|
||||
"app.poll.tf": "درست / نادرست",
|
||||
@ -275,6 +290,8 @@
|
||||
"app.poll.liveResult.usersTitle": "کاربران",
|
||||
"app.poll.liveResult.responsesTitle": "پاسخ",
|
||||
"app.poll.liveResult.secretLabel": "این یک نظرسنجی ناشناس است. پاسخ هر فرد نمایش داده نمیشود.",
|
||||
"app.poll.removePollOpt": "گزینه نظرسنجی حذف شد {0}",
|
||||
"app.poll.emptyPollOpt": "خالی",
|
||||
"app.polling.pollingTitle": "امکانات نظرسنجی",
|
||||
"app.polling.pollQuestionTitle": "سوال نظرسنجی",
|
||||
"app.polling.submitLabel": "ارسال",
|
||||
@ -338,6 +355,9 @@
|
||||
"app.actionsBar.raiseLabel": "اجازه گرفتن از استاد",
|
||||
"app.actionsBar.label": "نوار فعالیت ها",
|
||||
"app.actionsBar.actionsDropdown.restorePresentationLabel": "بازیابی ارائه",
|
||||
"app.actionsBar.actionsDropdown.restorePresentationDesc": "کلید برگرداندن ارائه بعد از کوچک کردن آن",
|
||||
"app.actionsBar.actionsDropdown.minimizePresentationLabel": "حداقل کردن پنجره ارائه",
|
||||
"app.actionsBar.actionsDropdown.minimizePresentationDesc": "کلید کوچک کردن ارائه",
|
||||
"app.screenshare.screenShareLabel" : "اشتراک صفحه",
|
||||
"app.submenu.application.applicationSectionTitle": "برنامه",
|
||||
"app.submenu.application.animationsLabel": "انیمیشن ها",
|
||||
@ -357,6 +377,7 @@
|
||||
"app.submenu.notification.pushAlertLabel": "هشدارهای پاپآپ",
|
||||
"app.submenu.notification.messagesLabel": "پیام گفتگو",
|
||||
"app.submenu.notification.userJoinLabel": "پیوستن کاربر",
|
||||
"app.submenu.notification.userLeaveLabel": "کاربر ترک کرد",
|
||||
"app.submenu.notification.guestWaitingLabel": "میهمان در انتظار پذیرفته شدن برای ورود به جلسه",
|
||||
"app.submenu.audio.micSourceLabel": "ورودی صدای میکروفن",
|
||||
"app.submenu.audio.speakerSourceLabel": "ورودی صدای بلندگو",
|
||||
@ -390,6 +411,8 @@
|
||||
"app.switch.offLabel": "خاموش",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "برای بی صدا کردن کاربر انتخاب کنید",
|
||||
"app.talkingIndicator.isTalking" : "{0} در حال صحبت کردن است",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+ در حال حرف زدن هستند",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+ حرف میزدند،",
|
||||
"app.talkingIndicator.wasTalking" : "{0} به صحبت خود پایان داد",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "فعالیت ها",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "مدیریت ارائه ها",
|
||||
@ -465,6 +488,8 @@
|
||||
"app.audioModal.ariaTitle": "ملحق شدن به مدال صدا",
|
||||
"app.audioModal.microphoneLabel": "میکروفون",
|
||||
"app.audioModal.listenOnlyLabel": "تنها شنونده",
|
||||
"app.audioModal.microphoneDesc": "ورود به کنفرانس صوتی با میکروفن",
|
||||
"app.audioModal.listenOnlyDesc": "ورود به کنفرانس صوتی به صورت شنونده",
|
||||
"app.audioModal.audioChoiceLabel": "چنانچه مایل هستید تا از امکانات صوتی ذیل استفاده کنید، روی آن کلیک نمایید.",
|
||||
"app.audioModal.iOSBrowser": "صدا/تصویر پیشتیبانی نمیشود",
|
||||
"app.audioModal.iOSErrorDescription": "در حال حاضر صدا و تصویر در مرورگر کروم iOS پشتیبانی نمیشود.",
|
||||
@ -490,6 +515,7 @@
|
||||
"app.audioModal.playAudio.arialabel" : "پخش صدا",
|
||||
"app.audioDial.tipIndicator": "نکته",
|
||||
"app.audioDial.tipMessage": "برای قطع/وصل صدا کلید 0 را روی موبایل خود شماره گیری کنید",
|
||||
"app.audioModal.connecting": "برقراری ارتباط صوتی",
|
||||
"app.audioManager.joinedAudio": "شما به جلسه صوتی وارد شده اید",
|
||||
"app.audioManager.joinedEcho": "شما به تست اکو پیوسته اید",
|
||||
"app.audioManager.leftAudio": "شما جلسه صوتی را ترک کرده اید",
|
||||
@ -546,6 +572,7 @@
|
||||
"app.error.401": "احراز هویت نشده",
|
||||
"app.error.403": "شما از جلسه حذف شدید",
|
||||
"app.error.404": "پیدا نشد",
|
||||
"app.error.408": "تایید هویت شکست خورد",
|
||||
"app.error.410": "جلسه پایان یافت",
|
||||
"app.error.500": "آخ، خطای پیش آمده است",
|
||||
"app.error.userLoggedOut": "کاربر به خاطر خروج sessionToken غیر معتبر دارد",
|
||||
@ -567,6 +594,7 @@
|
||||
"app.guest.guestWait": "لطفا منتظر بمانید تا یک مدیر شما را برای پیوستن به جلسه تایید کند.",
|
||||
"app.guest.guestDeny": "میهمان از پیوستن به اتاق سر باز زد.",
|
||||
"app.guest.seatWait": "میهمان در انتظار اجازه ورود به اتاق میباشد.",
|
||||
"app.guest.allow": "میربان تائید شد و به جلسه هدایت گردید.",
|
||||
"app.userList.guest.waitingUsers": "کاربران در حال انتظار",
|
||||
"app.userList.guest.waitingUsersTitle": "مدیرت کاربران",
|
||||
"app.userList.guest.optionTitle": "بررسی کاربران در انتظار تایید",
|
||||
@ -598,6 +626,7 @@
|
||||
"app.notification.recordingPaused": "جلسه دیگر ضبط نمیشود",
|
||||
"app.notification.recordingAriaLabel": "زمان ضبط شده",
|
||||
"app.notification.userJoinPushAlert": "{0} به کلاس پیوستند",
|
||||
"app.notification.userLeavePushAlert": "{0} جلسه را ترک کرد",
|
||||
"app.submenu.notification.raiseHandLabel": "بالا بردن دست",
|
||||
"app.shortcut-help.title": "میانبرهای صفحه کلید",
|
||||
"app.shortcut-help.accessKeyNotAvailable": "کلیدهای دسترسی موجود نیست",
|
||||
@ -641,14 +670,25 @@
|
||||
"app.guest-policy.button.askModerator": "از مدیر تقاضا کن",
|
||||
"app.guest-policy.button.alwaysAccept": "همیشه بپذیر",
|
||||
"app.guest-policy.button.alwaysDeny": "همیشه رد کن",
|
||||
"app.guest-policy.policyBtnDesc": "تنظیم سیاست میهمان",
|
||||
"app.connection-status.ariaTitle": "کیفیت وضعیت اتصال",
|
||||
"app.connection-status.title": "وضعیت اتصال",
|
||||
"app.connection-status.description": "وضعیت اتصال کاربران را مشاهده کنید",
|
||||
"app.connection-status.empty": "در حال حاضر هیچ مشکلی در رابطه با اتصال گزارش نشده است",
|
||||
"app.connection-status.more": "بیشتر",
|
||||
"app.connection-status.copy": "نسخهبرداری از دادههای شبکه",
|
||||
"app.connection-status.copied": "کپی شد!",
|
||||
"app.connection-status.jitter": "تکان دادن",
|
||||
"app.connection-status.label": "وضعیت اتصال",
|
||||
"app.connection-status.no": "خیر",
|
||||
"app.connection-status.notification": "قطعی در اتصال شما پیدا شد",
|
||||
"app.connection-status.offline": "برون خط",
|
||||
"app.connection-status.lostPackets": "پکتهای از دست رفته",
|
||||
"app.connection-status.usingTurn": "استفاده از TURN",
|
||||
"app.connection-status.yes": "بله",
|
||||
"app.learning-dashboard.label": "داشبورد یادگیری",
|
||||
"app.learning-dashboard.description": "باز کردن داشبورد با فعالیتهای کاربران",
|
||||
"app.learning-dashboard.clickHereToOpen": "نمایش داشبورد یادگیری",
|
||||
"app.recording.startTitle": "شروع ضبط",
|
||||
"app.recording.stopTitle": "مکث ضبط",
|
||||
"app.recording.resumeTitle": "از سر گرفتن ضبط",
|
||||
@ -671,6 +711,7 @@
|
||||
"app.videoPreview.webcamPreviewLabel": "پیش نمایش دوربین",
|
||||
"app.videoPreview.webcamSettingsTitle": "تنظیمات دوربین",
|
||||
"app.videoPreview.webcamVirtualBackgroundLabel": "تنظیمات پسزمینه مجازی",
|
||||
"app.videoPreview.webcamVirtualBackgroundDisabledLabel": "این دستگاه از پسزمینههای مجازی پشتیبانی نمیکند",
|
||||
"app.videoPreview.webcamNotFoundLabel": "دوربین یافت نشد",
|
||||
"app.videoPreview.profileNotFoundLabel": "پروفایل دوربین پیشتیبانی نمیشود",
|
||||
"app.video.joinVideo": "اشتراک گذاری دوربین",
|
||||
@ -709,6 +750,8 @@
|
||||
"app.video.virtualBackground.none": "هیچی",
|
||||
"app.video.virtualBackground.blur": "محو کردن",
|
||||
"app.video.virtualBackground.genericError": "افکت دوربین اعمال نشد. مجددا تلاش کنید.",
|
||||
"app.video.virtualBackground.camBgAriaDesc": "تنظیم پسزمینه مجازی دوربین به {0}",
|
||||
"app.video.dropZoneLabel": "اینجا بیندازید",
|
||||
"app.fullscreenButton.label": "تغییر {0} به تمام صفحه",
|
||||
"app.fullscreenUndoButton.label": "{0} تمام صفحه را واگرد کنید",
|
||||
"app.switchButton.expandLabel": "گسترش اشتراکگذاری صفحهنمایش",
|
||||
@ -756,6 +799,7 @@
|
||||
"app.whiteboard.toolbar.palmRejectionOn": "تماس روشن",
|
||||
"app.whiteboard.toolbar.palmRejectionOff": "تماس خاموش",
|
||||
"app.whiteboard.toolbar.fontSize": "لیست اندازه قلم",
|
||||
"app.whiteboard.toolbarAriaLabel": "ابزارهای ارائه",
|
||||
"app.feedback.title": "شما از کنفرانس خارج شده اید",
|
||||
"app.feedback.subtitle": "بسیار ممنون میشویم نظر خود را در خصوص استفاده از برنامه بفرمایید (اختیاری)",
|
||||
"app.feedback.textarea": "چگونه میتوانیم برنامه بیگ بلو باتن را بهبود دهیم؟",
|
||||
@ -774,7 +818,9 @@
|
||||
"app.createBreakoutRoom.title": "اتاقهای زیرمجموعه",
|
||||
"app.createBreakoutRoom.ariaTitle": "پنهان کردن اتاقهای زیرمجموعه",
|
||||
"app.createBreakoutRoom.breakoutRoomLabel": "اتاقهای زیرمجموعه {0}",
|
||||
"app.createBreakoutRoom.askToJoin": "درخواست برای ملحق شدن",
|
||||
"app.createBreakoutRoom.generatingURL": "در حال تولید نشانی وب",
|
||||
"app.createBreakoutRoom.generatingURLMessage": "ما در حال ایجاد یک نشانی اینترنتی اتصال برای اتاق زیر مجموعه انتخابشده هستیم. شاید چند ثانیه طول بکشد …",
|
||||
"app.createBreakoutRoom.duration": "مدت زمان {0}",
|
||||
"app.createBreakoutRoom.room": "اتاق {0}",
|
||||
"app.createBreakoutRoom.notAssigned": "واگذار نشده ({0})",
|
||||
@ -787,6 +833,7 @@
|
||||
"app.createBreakoutRoom.numberOfRooms": "تعداد اتاقها",
|
||||
"app.createBreakoutRoom.durationInMinutes": "مدت زمان (دقیقه)",
|
||||
"app.createBreakoutRoom.randomlyAssign": "به صورت تصادفی واگذار شده",
|
||||
"app.createBreakoutRoom.randomlyAssignDesc": "توزیع تصادفی کاربران به اتاقهای زیر مجموعه",
|
||||
"app.createBreakoutRoom.endAllBreakouts": "پایان تمام اتاقهای زیرمجموعه",
|
||||
"app.createBreakoutRoom.roomName": "{0} (اتاق - {1})",
|
||||
"app.createBreakoutRoom.doneLabel": "انجام شد",
|
||||
@ -806,6 +853,7 @@
|
||||
"app.createBreakoutRoom.extendTimeLabel": "گسترش",
|
||||
"app.createBreakoutRoom.extendTimeCancel": "لغو",
|
||||
"app.createBreakoutRoom.extendTimeHigherThanMeetingTimeError": "مدت زمان اتاقها نمیتواند از زمان جلسه بیشتر باشه.",
|
||||
"app.createBreakoutRoom.roomNameInputDesc": "به روز رسانی نام اتاقهای زیر مجموعه",
|
||||
"app.externalVideo.start": "به اشتراک گذاری ویدئو جدید",
|
||||
"app.externalVideo.title": "اشتراک یک ویدیوی خارجی",
|
||||
"app.externalVideo.input": "آدرس ویدیوی خارجی",
|
||||
@ -813,6 +861,7 @@
|
||||
"app.externalVideo.urlError": "آدرس این فیلم نامعتبر است",
|
||||
"app.externalVideo.close": "بستن",
|
||||
"app.externalVideo.autoPlayWarning": "برای به هنگام سازی ، ویدیو را پخش کنید",
|
||||
"app.externalVideo.refreshLabel": "تازه سازی پخش کننده ویدئو",
|
||||
"app.externalVideo.noteLabel": "نکته: ویدیوهای خارجی به اشتراک گذاشته شده در ضبط ظاهر نمیشوند.نشانیهای وب یوتیوب، ویمیو، Instructure Media، توییچ، دیلیموشن و فایلهای رسانهای (به عنوان مثال https://example.com/xy.mp4) پشتیبانی میشوند.",
|
||||
"app.actionsBar.actionsDropdown.shareExternalVideo": "اشتراک یک ویدیوی خارجی",
|
||||
"app.actionsBar.actionsDropdown.stopShareExternalVideo": "متوقف کردن نمایش ویدیوی خارجی",
|
||||
@ -831,6 +880,8 @@
|
||||
"app.layout.style.smart": "چینش هوشمند",
|
||||
"app.layout.style.presentationFocus": "تأکید بر نمایش",
|
||||
"app.layout.style.videoFocus": "تأکید بر فیلم",
|
||||
"app.layout.style.presentationFocusPush": "تمرکز روی ارائه (قالب برای همه اعمال شود)",
|
||||
"app.layout.style.videoFocusPush": "تمرکز روی ویدئو (قالب برای همه اعمال شود)",
|
||||
"playback.button.about.aria": "درباره",
|
||||
"playback.button.clear.aria": "پاکسازی جستجو",
|
||||
"playback.button.close.aria": "بستن مودال",
|
||||
@ -858,7 +909,35 @@
|
||||
"playback.player.search.modal.title": "جستجو",
|
||||
"playback.player.search.modal.subtitle": "یافتن محتوای صفحات ارائه شده",
|
||||
"playback.player.thumbnails.wrapper.aria": "محدوده تصاویر بندانگشتی",
|
||||
"playback.player.video.wrapper.aria": "محدوده فیلم"
|
||||
"playback.player.video.wrapper.aria": "محدوده فیلم",
|
||||
"app.learningDashboard.dashboardTitle": "داشبورد یادگیری",
|
||||
"app.learningDashboard.user": "کاربر",
|
||||
"app.learningDashboard.indicators.meetingStatusEnded": "پایان یافته",
|
||||
"app.learningDashboard.indicators.meetingStatusActive": "فعال",
|
||||
"app.learningDashboard.indicators.usersOnline": "کاربران فعال",
|
||||
"app.learningDashboard.indicators.usersTotal": "تعداد کل کاربران",
|
||||
"app.learningDashboard.indicators.polls": "نظرسنجیها",
|
||||
"app.learningDashboard.indicators.raiseHand": "دستهای بالا رفته",
|
||||
"app.learningDashboard.indicators.activityScore": "امتیاز فعالیت",
|
||||
"app.learningDashboard.indicators.duration": "مدت زمان",
|
||||
"app.learningDashboard.usersTable.title": "مرور کلی",
|
||||
"app.learningDashboard.usersTable.colOnline": "زمان آنلاین بودن",
|
||||
"app.learningDashboard.usersTable.colTalk": "زمان صحبت کردن",
|
||||
"app.learningDashboard.usersTable.colWebcam": "زمان فعالیت دوربین",
|
||||
"app.learningDashboard.usersTable.colMessages": "پیامها",
|
||||
"app.learningDashboard.usersTable.colEmojis": "ایموجیها",
|
||||
"app.learningDashboard.usersTable.colRaiseHands": "دستهای بالا برده شده",
|
||||
"app.learningDashboard.usersTable.colActivityScore": "امتیاز فعالیت",
|
||||
"app.learningDashboard.usersTable.colStatus": "وضعیت",
|
||||
"app.learningDashboard.usersTable.userStatusOnline": "آنلاین",
|
||||
"app.learningDashboard.usersTable.userStatusOffline": "آفلاین",
|
||||
"app.learningDashboard.usersTable.noUsers": "کاربری نیست",
|
||||
"app.learningDashboard.pollsTable.title": "نظرسنجی",
|
||||
"app.learningDashboard.pollsTable.anonymousAnswer": "نظرسنجی ناشناس (پاسخها در ردیف آخر)",
|
||||
"app.learningDashboard.pollsTable.anonymousRowName": "ناشناس",
|
||||
"app.learningDashboard.statusTimelineTable.title": "جدول زمانی وضعیت",
|
||||
"app.learningDashboard.errors.invalidToken": "توکن نشست نامعتبر است",
|
||||
"app.learningDashboard.errors.dataUnavailable": "داده دیگر موجود نیست"
|
||||
|
||||
}
|
||||
|
||||
|
@ -390,7 +390,7 @@
|
||||
"app.submenu.video.participantsCamLabel": "参加者のウェブカメラを見ています",
|
||||
"app.settings.applicationTab.label": "アプリケーション",
|
||||
"app.settings.audioTab.label": "音声",
|
||||
"app.settings.videoTab.label": "ビデオ",
|
||||
"app.settings.videoTab.label": "映像",
|
||||
"app.settings.usersTab.label": "参加者",
|
||||
"app.settings.main.label": "設定",
|
||||
"app.settings.main.cancel.label": "キャンセル",
|
||||
@ -410,8 +410,10 @@
|
||||
"app.switch.onLabel": "入",
|
||||
"app.switch.offLabel": "切",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "ユーザーをミュートします",
|
||||
"app.talkingIndicator.isTalking" : "{0} が話しています",
|
||||
"app.talkingIndicator.wasTalking" : "{0} が話し終えました",
|
||||
"app.talkingIndicator.isTalking" : "{0}人が話しています",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+人が話しています",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+人が話していました。",
|
||||
"app.talkingIndicator.wasTalking" : "{0}人が話し終えました",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "アクション",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "プレゼンテーションを管理する",
|
||||
"app.actionsBar.actionsDropdown.initPollLabel": "投票を初期化",
|
||||
@ -671,10 +673,10 @@
|
||||
"app.guest-policy.policyBtnDesc": "会議のゲストポリシーを設定",
|
||||
"app.connection-status.ariaTitle": "接続状況モーダル",
|
||||
"app.connection-status.title": "接続状況",
|
||||
"app.connection-status.description": "ユーザの接続状況をみる",
|
||||
"app.connection-status.description": "ユーザーの接続状況の閲覧",
|
||||
"app.connection-status.empty": "現在のところ接続の問題は報告されていません。",
|
||||
"app.connection-status.more": "更に見る",
|
||||
"app.connection-status.copy": "ネットワークデータをコピーする",
|
||||
"app.connection-status.copy": "ネットワークの情報をコピー",
|
||||
"app.connection-status.copied": "コピーしました!",
|
||||
"app.connection-status.jitter": "ジッター",
|
||||
"app.connection-status.label": "接続状況",
|
||||
@ -910,6 +912,8 @@
|
||||
"playback.player.video.wrapper.aria": "ビデオエリア",
|
||||
"app.learningDashboard.dashboardTitle": "ラーニングダッシュボード",
|
||||
"app.learningDashboard.user": "ユーザー",
|
||||
"app.learningDashboard.shareButton": "共有する",
|
||||
"app.learningDashboard.shareLinkCopied": "リンクがコピーされました",
|
||||
"app.learningDashboard.indicators.meetingStatusEnded": "終了",
|
||||
"app.learningDashboard.indicators.meetingStatusActive": "会議中",
|
||||
"app.learningDashboard.indicators.usersOnline": "人のアクティブなユーザー",
|
||||
@ -919,7 +923,7 @@
|
||||
"app.learningDashboard.indicators.activityScore": "アクティビティスコア",
|
||||
"app.learningDashboard.indicators.duration": "時間",
|
||||
"app.learningDashboard.usersTable.title": "概要",
|
||||
"app.learningDashboard.usersTable.colOnline": "オンラインの時間",
|
||||
"app.learningDashboard.usersTable.colOnline": "オンライン時間",
|
||||
"app.learningDashboard.usersTable.colTalk": "会話時間",
|
||||
"app.learningDashboard.usersTable.colWebcam": "カメラオン時間",
|
||||
"app.learningDashboard.usersTable.colMessages": "メッセージ",
|
||||
|
@ -411,6 +411,8 @@
|
||||
"app.switch.offLabel": "ВЫКЛ",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "Нажмите, чтобы выключить микрофон пользователю",
|
||||
"app.talkingIndicator.isTalking" : "{0} говорит",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+ говорят",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+ разговаривают",
|
||||
"app.talkingIndicator.wasTalking" : "{0} прекратил говорить",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "Действия",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "Управление презентациями",
|
||||
@ -816,6 +818,7 @@
|
||||
"app.createBreakoutRoom.title": "Комнаты для групповой работы",
|
||||
"app.createBreakoutRoom.ariaTitle": "Скрыть комнаты для групповой работы",
|
||||
"app.createBreakoutRoom.breakoutRoomLabel": "Комнаты для групповой работы {0} ",
|
||||
"app.createBreakoutRoom.askToJoin": "Спрашивать для подключения",
|
||||
"app.createBreakoutRoom.generatingURL": "Генерация URL-адреса",
|
||||
"app.createBreakoutRoom.generatingURLMessage": "Мы создаем URL-адрес для присоединения к выбранной комнате для обсуждения. Это может занять несколько секунд...",
|
||||
"app.createBreakoutRoom.duration": "Продолжительность {0}",
|
||||
@ -877,8 +880,8 @@
|
||||
"app.layout.style.smart": "Автоматический",
|
||||
"app.layout.style.presentationFocus": "Фокус на презентации",
|
||||
"app.layout.style.videoFocus": "Фокус на веб-камерах",
|
||||
"app.layout.style.presentationFocusPush": "Фокус на презентации (Применить компоновку для всех)",
|
||||
"app.layout.style.videoFocusPush": "Фокус на веб-камерах (Применить компоновку для всех)",
|
||||
"app.layout.style.presentationFocusPush": "Фокус на презентации (Применить для всех)",
|
||||
"app.layout.style.videoFocusPush": "Фокус на веб-камерах (Применить для всех)",
|
||||
"playback.button.about.aria": "О",
|
||||
"playback.button.clear.aria": "Очистить поиск",
|
||||
"playback.button.close.aria": "Закрыть модальное окно",
|
||||
@ -920,7 +923,7 @@
|
||||
"app.learningDashboard.usersTable.title": "Обзор",
|
||||
"app.learningDashboard.usersTable.colOnline": "Время онлайна",
|
||||
"app.learningDashboard.usersTable.colTalk": "Время разговора",
|
||||
"app.learningDashboard.usersTable.colWebcam": "Время с вкл. веб-камерой",
|
||||
"app.learningDashboard.usersTable.colWebcam": "Время с веб-камерой",
|
||||
"app.learningDashboard.usersTable.colMessages": "Сообщений",
|
||||
"app.learningDashboard.usersTable.colEmojis": "Смайликов",
|
||||
"app.learningDashboard.usersTable.colRaiseHands": "Поднятых рук",
|
||||
|
@ -25,6 +25,8 @@
|
||||
"app.chat.multi.typing": "బహుళ వినియోగదారులు టైప్ చేస్తున్నారు",
|
||||
"app.chat.one.typing": "{0} టైప్ చేస్తున్నారు",
|
||||
"app.chat.two.typing": "{0} , {1} టైప్ చేస్తున్నారు",
|
||||
"app.chat.copySuccess": "రాయబడిన చాట్ కాపీ చేయబడింది",
|
||||
"app.chat.copyErr": "చాట్ ట్రాన్స్క్రిప్ట్ని కాపీ చేయడం విఫలమైంది",
|
||||
"app.captions.label": "శీర్షికలు",
|
||||
"app.captions.menu.close": "మూసివేయి",
|
||||
"app.captions.menu.start": "ప్రారంభించు",
|
||||
@ -49,7 +51,9 @@
|
||||
"app.captions.pad.dictationStop": "డిక్టేషన్ ఆపుము",
|
||||
"app.captions.pad.dictationOnDesc": "మాటల గుర్తింపును ఆన్ చేయండి",
|
||||
"app.captions.pad.dictationOffDesc": " మాటల గుర్తింపును ఆపివేస్తుంది",
|
||||
"app.captions.pad.speechRecognitionStop": "బ్రౌజర్ అననుకూలత లేదా కొంత సమయం నిశ్శబ్దం కారణంగా మాటను గుర్తించుట నిలిపివేయబడింది",
|
||||
"app.textInput.sendLabel": "పంపండి",
|
||||
"app.title.defaultViewLabel": "డిఫాల్ట్ ప్రెజెంటేషన్ వ్యూ",
|
||||
"app.note.title": "షేర్డ్ నోట్సు",
|
||||
"app.note.label": "నోటు",
|
||||
"app.note.hideNoteLabel": "నోటును దాచండి",
|
||||
@ -73,7 +77,10 @@
|
||||
"app.userList.moderator": "మోడరేటర్",
|
||||
"app.userList.mobile": "మొబైల్",
|
||||
"app.userList.guest": "అతిథి",
|
||||
"app.userList.sharingWebcam": "వెబ్క్యామ్",
|
||||
"app.userList.menuTitleContext": "అందుబాటులో ఉన్న ఎంపికలు",
|
||||
"app.userList.chatListItem.unreadSingular": "ఒక కొత్త సందేశం",
|
||||
"app.userList.chatListItem.unreadPlural": "{0} కొత్త సందేశాలు",
|
||||
"app.userList.menu.chat.label": "ప్రైవేట్ చాట్ ప్రారంభించండి",
|
||||
"app.userList.menu.clearStatus.label": "స్టేటస్ ని క్లియర్ చేయండి",
|
||||
"app.userList.menu.removeUser.label": "వినియోగదారుని తొలగించండి",
|
||||
@ -118,7 +125,7 @@
|
||||
"app.userList.userOptions.enableNote": "షేర్డ్ నోట్సులు ఇప్పుడు ప్రారంభించబడ్డాయి",
|
||||
"app.userList.userOptions.showUserList": "వినియోగదారుని జాబితా ఇప్పుడు వీక్షకులకు చూపబడింది",
|
||||
"app.userList.userOptions.enableOnlyModeratorWebcam": "మీరు ఇప్పుడు మీ వెబ్క్యామ్ను ఆన్ చేయవచ్చు,అందరూ మిమ్మల్ని చూస్తారు",
|
||||
"app.userList.userOptions.savedNames.title": "{1 meeting వద్ద {0 meeting ను కలవడంలో వినియోగదారుల జాబితా",
|
||||
"app.userList.userOptions.savedNames.title": "{0} సమావేశంలో ఉన్న వినియోగదారుల జాబితా {1} వద్ద",
|
||||
"app.userList.userOptions.sortedFirstName.heading": "మొదటి పేరుతో క్రమబద్ధీకరించబడింది:",
|
||||
"app.userList.userOptions.sortedLastName.heading": "చివరి పేరుతో క్రమబద్ధీకరించబడింది:",
|
||||
"app.media.label": "మీడియా",
|
||||
@ -129,6 +136,9 @@
|
||||
"app.media.screenshare.notSupported": "ఈ బ్రౌజర్లో స్క్రీన్షేరింగ్కు మద్దతు లేదు.",
|
||||
"app.media.screenshare.autoplayBlockedDesc": "ప్రెజెంటర్ స్క్రీన్ను మీకు చూపించడానికి మాకు మీ అనుమతి అవసరం.",
|
||||
"app.media.screenshare.autoplayAllowLabel": "షేర్ద్ స్క్రీన్ ను చూడండి",
|
||||
"app.screenshare.presenterLoadingLabel": "మీ స్క్రీన్ షేర్ లోడ్ అవుతోంది",
|
||||
"app.screenshare.viewerLoadingLabel": "ప్రెజెంటర్ స్క్రీన్ లోడ్ అవుతోంది",
|
||||
"app.screenshare.presenterSharingLabel": "మీరు ఇప్పుడు మీ స్క్రీన్ను షేర్ చేస్తున్నారు",
|
||||
"app.screenshare.screenshareFinalError": "కోడ్ {0}. స్క్రీన్ను భాగస్వామ్యం చేయలేకపోయింది.",
|
||||
"app.screenshare.screenshareRetryError": "కోడ్ {0}. స్క్రీన్ను మళ్లీ భాగస్వామ్యం చేయడానికి ప్రయత్నించండి.",
|
||||
"app.screenshare.screenshareRetryOtherEnvError": "కోడ్ {0}. స్క్రీన్ను భాగస్వామ్యం చేయలేకపోయింది. వేరే బ్రౌజర్ లేదా పరికరాన్ని ఉపయోగించి మళ్లీ ప్రయత్నించండి.",
|
||||
@ -137,6 +147,9 @@
|
||||
"app.meeting.ended": "ఈ సెషన్ ముగిసింది",
|
||||
"app.meeting.meetingTimeRemaining": "సమావేశ సమయం మిగిలి ఉంది: {0}",
|
||||
"app.meeting.meetingTimeHasEnded": "సమయం ముగిసింది. సమావేశం త్వరలో ముగుస్తుంది",
|
||||
"app.meeting.endedByUserMessage": "ఈ సెషన్ {0} ద్వారా ముగించబండింది",
|
||||
"app.meeting.endedByNoModeratorMessageSingular": "మోడరేటర్ లేనందున ఒక నిమిషం తర్వాత సమావేశం ముగిసింది",
|
||||
"app.meeting.endedByNoModeratorMessagePlural": "మోడరేటర్ లేనందున {0} నిమిషాల తర్వాత సమావేశం ముగిసింది",
|
||||
"app.meeting.endedMessage": "మీరు హోమ్ స్క్రీన్కు తిరిగి ఫార్ వర్డ్ చేయబడతారు",
|
||||
"app.meeting.alertMeetingEndsUnderMinutesSingular": "సమావేశం ఒక నిమిషంలో ముగుస్తుంది.",
|
||||
"app.meeting.alertMeetingEndsUnderMinutesPlural": "సమావేశం {0} నిమిషాల్లో ముగుస్తుంది.",
|
||||
@ -173,6 +186,7 @@
|
||||
"app.presentation.presentationToolbar.fitToWidth": "వెడల్పుకు సరిపెట్టు",
|
||||
"app.presentation.presentationToolbar.fitToPage": "పేజీకి సరిపెట్టు",
|
||||
"app.presentation.presentationToolbar.goToSlide": "స్లయిడ్ {0}",
|
||||
"app.presentation.placeholder": "ప్రదర్శన అప్లోడ్ చేయడానికి వేచి ఉంది",
|
||||
"app.presentationUploder.title": "ప్రదర్శన",
|
||||
"app.presentationUploder.message": "ప్రెజెంటర్గా మీకు ఏదైనా కార్యాలయ పత్రం లేదా PDF ఫైల్ను అప్లోడ్ చేసే సామర్థ్యం ఉంది. ఉత్తమ ఫలితాల కోసం మేము PDF ఫైల్ను సిఫార్సు చేస్తున్నాము. దయచేసి కుడి వైపున ఉన్న సర్కిల్ చెక్బాక్స్ ఉపయోగించి ప్రదర్శనను ఎంచుకున్నారని నిర్ధారించుకోండి.",
|
||||
"app.presentationUploder.uploadLabel": "అప్లోడ్ ",
|
||||
@ -198,7 +212,7 @@
|
||||
"app.presentationUploder.conversion.generatingThumbnail": "తంబ్ నైల్స్ రూపొందుతున్నాయి ...",
|
||||
"app.presentationUploder.conversion.generatedSlides": "స్లయిడ్ లు రూపొందాయి ...",
|
||||
"app.presentationUploder.conversion.generatingSvg": "SVG చిత్రాలు రూపొందుతున్నాయి...",
|
||||
"app.presentationUploder.conversion.pageCountExceeded": "పేజీల సంఖ్య గరిష్టంగా {0 మించిపోయింది",
|
||||
"app.presentationUploder.conversion.pageCountExceeded": "పేజీల సంఖ్య గరిష్టంగా {0} మించిపోయింది",
|
||||
"app.presentationUploder.conversion.officeDocConversionInvalid": "ఆఫీస్ డాక్యుమెంట్ ప్రాసెస్ చేయడంలో విఫలమైంది. బదులుగా ఒక PDF ని అప్లోడ్ చేయండి.",
|
||||
"app.presentationUploder.conversion.officeDocConversionFailed": "ఆఫీస్ డాక్యుమెంట్ ప్రాసెస్ చేయడంలో విఫలమైంది. బదులుగా ఒక PDF ని అప్లోడ్ చేయండి.",
|
||||
"app.presentationUploder.conversion.pdfHasBigPage": "మేము PDF ఫైల్ను మార్చలేకపోయాము, దయచేసి దాన్ని ఆప్టిమైజ్ చేయడానికి ప్రయత్నించండి. గరిష్ట పేజీ పరిమాణం {0}",
|
||||
@ -219,6 +233,7 @@
|
||||
"app.presentationUploder.itemPlural" : "అంశాలు",
|
||||
"app.presentationUploder.clearErrors": "లోపాలను క్లియర్ చేయండి",
|
||||
"app.presentationUploder.clearErrorsDesc": "విఫలమైన ప్రదర్శన అప్లోడ్లను క్లియర్ చేస్తుంది",
|
||||
"app.presentationUploder.uploadViewTitle": "ప్రదర్శనను అప్లోడ్ చేయండి",
|
||||
"app.poll.pollPaneTitle": "పోలింగ్",
|
||||
"app.poll.quickPollTitle": "తక్షణ ఎన్నిక",
|
||||
"app.poll.hidePollDesc": "పోల్ మెను పేన్ను దాచిపెడుతుంది",
|
||||
@ -234,6 +249,8 @@
|
||||
"app.poll.customPlaceholder": "పోల్ ఎంపికను జోడించండి",
|
||||
"app.poll.noPresentationSelected": "ప్రదర్శన ఏదీ ఎంచుకోబడలేదు! దయచేసి ఒకదాన్ని ఎంచుకోండి.",
|
||||
"app.poll.clickHereToSelect": "ఎంచుకోవడానికి ఇక్కడ క్లిక్ చేయండి",
|
||||
"app.poll.question.label" : "మీ ప్రశ్న రాయండి ...",
|
||||
"app.poll.optionalQuestion.label" : "మీ ప్రశ్న రాయండి (మీకు ఇష్టమైతే)...",
|
||||
"app.poll.userResponse.label" : "వినియోగదారు ప్రతిస్పందన",
|
||||
"app.poll.responseTypes.label" : "ప్రతిస్పందన రకాలు",
|
||||
"app.poll.optionDelete.label" : "తొలగించు",
|
||||
@ -241,14 +258,21 @@
|
||||
"app.poll.typedResponse.desc" : "వినియోగదారులు వారి ప్రతిస్పందనను పూరించడానికి టెక్స్ట్ బాక్స్తో ప్రదర్శించబడతారు.",
|
||||
"app.poll.addItem.label" : "వస్తువు జోడించు",
|
||||
"app.poll.start.label" : "పోల్ ప్రారంభించండి",
|
||||
"app.poll.secretPoll.label" : "అనామక పోల్",
|
||||
"app.poll.secretPoll.isSecretLabel": "పోల్ అనామకంగా ఉంది - మీరు వ్యక్తిగత ప్రతిస్పందనలను చూడలేరు.",
|
||||
"app.poll.questionErr": "ఒక ప్రశ్న అందించడం అవసరం.",
|
||||
"app.poll.optionErr": "పోల్ ఎంపికను నమోదు చేయండి",
|
||||
"app.poll.startPollDesc": "పోల్ ప్రారంభమవుతుంది\n ",
|
||||
"app.poll.showRespDesc": "ప్రతిస్పందన అమరిక ప్రదర్శిస్తుంది",
|
||||
"app.poll.addRespDesc": "పోల్ స్పందన ఇన్పుట్ను జతచేస్తుంది",
|
||||
"app.poll.deleteRespDesc": "ఎంపికను తీసివేస్తుంది {0}",
|
||||
"app.poll.t": "ఒప్పు",
|
||||
"app.poll.f": "తప్పు",
|
||||
"app.poll.tf": "ఒప్పు/తప్పు",
|
||||
"app.poll.y": "అవును",
|
||||
"app.poll.n": "కాదు",
|
||||
"app.poll.abstention": "సంయమనం",
|
||||
"app.poll.yna": "అవును / కాదు / సంయమనం",
|
||||
"app.poll.abstention": "తిరస్కరించు",
|
||||
"app.poll.yna": "అవును / కాదు / తిరస్కరించు",
|
||||
"app.poll.a2": "A/B",
|
||||
"app.poll.a3": "A / B / C",
|
||||
"app.poll.a4": "A / B / C / D",
|
||||
@ -257,7 +281,7 @@
|
||||
"app.poll.answer.false": "తప్పు",
|
||||
"app.poll.answer.yes": "అవును",
|
||||
"app.poll.answer.no": "కాదు",
|
||||
"app.poll.answer.abstention": "సంయమనం",
|
||||
"app.poll.answer.abstention": "తిరస్కరించు",
|
||||
"app.poll.answer.a": "A",
|
||||
"app.poll.answer.b": "B",
|
||||
"app.poll.answer.c": "C",
|
||||
@ -265,11 +289,16 @@
|
||||
"app.poll.answer.e": "E",
|
||||
"app.poll.liveResult.usersTitle": "వినియోగదారులు",
|
||||
"app.poll.liveResult.responsesTitle": "స్పందన",
|
||||
"app.poll.liveResult.secretLabel": "ఇది అనామక పోల్. వ్యక్తిగత స్పందనలు చూపబడలేదు.",
|
||||
"app.poll.removePollOpt": "తీసివేసిన పోల్ ఎంపిక {0}",
|
||||
"app.poll.emptyPollOpt": "ఖాళీ",
|
||||
"app.polling.pollingTitle": "పోలింగ్ ఎంపికలు",
|
||||
"app.polling.pollQuestionTitle": "పోలింగ్ ప్రశ్న",
|
||||
"app.polling.submitLabel": "సమర్పించండి",
|
||||
"app.polling.submitAriaLabel": "పోల్ ప్రతిస్పందనను సమర్పించండి",
|
||||
"app.polling.responsePlaceholder": "సమాధానం నమోదు చేయండి",
|
||||
"app.polling.responseSecret": "అనామక పోల్ - ప్రెజెంటర్ మీ సమాధానం చూడలేరు.",
|
||||
"app.polling.responseNotSecret": "సాధారణ పోల్ - ప్రెజెంటర్ మీ సమాధానాన్ని చూడగలరు.",
|
||||
"app.polling.pollAnswerLabel": "పోల్ సమాధానం {0}",
|
||||
"app.polling.pollAnswerDesc": "{0} కు ఓటు వేయడానికి ఈ ఎంపికను ఎంచుకోండి",
|
||||
"app.failedMessage": "క్షమాపణలు, సర్వర్కు కనెక్ట్ చేయడంలో ఇబ్బంది.",
|
||||
@ -326,6 +355,9 @@
|
||||
"app.actionsBar.raiseLabel": "పెంచడం",
|
||||
"app.actionsBar.label": "చర్యల పట్టీ",
|
||||
"app.actionsBar.actionsDropdown.restorePresentationLabel": "ప్రదర్శనను పునరుద్ధరించండి",
|
||||
"app.actionsBar.actionsDropdown.restorePresentationDesc": " ప్రదర్శనను తగ్గించిన తర్వాత దాన్ని పునరుద్ధరించె బటన్",
|
||||
"app.actionsBar.actionsDropdown.minimizePresentationLabel": "ప్రదర్శన తగ్గించు",
|
||||
"app.actionsBar.actionsDropdown.minimizePresentationDesc": "ప్రదర్శనను తగ్గించడానికి ఉపయోగించే బటన్",
|
||||
"app.screenshare.screenShareLabel" : "స్క్రీన్ షేర్",
|
||||
"app.submenu.application.applicationSectionTitle": "అప్లికేషన్",
|
||||
"app.submenu.application.animationsLabel": "యానిమేషన్లు",
|
||||
@ -337,13 +369,15 @@
|
||||
"app.submenu.application.languageLabel": "అప్లికేషన్ భాష",
|
||||
"app.submenu.application.languageOptionLabel": "భాషను ఎంచుకోండి",
|
||||
"app.submenu.application.noLocaleOptionLabel": "చురుకైన స్థానికులు లేరు",
|
||||
"app.submenu.application.paginationEnabledLabel": "వీడియో pagination",
|
||||
"app.submenu.application.paginationEnabledLabel": "వీడియో పేజీజినేషన్",
|
||||
"app.submenu.application.layoutOptionLabel": "లేఅవుట్ రకం",
|
||||
"app.submenu.notification.SectionTitle": "నోటిఫికేషన్స్",
|
||||
"app.submenu.notification.Desc": "మీకు ఎలా మరియు ఏమి తెలియజేయబడుతుందో చెప్పండి",
|
||||
"app.submenu.notification.audioAlertLabel": "ఆడియో హెచ్చరికలు",
|
||||
"app.submenu.notification.pushAlertLabel": "పాపప్ హెచ్చరికలు",
|
||||
"app.submenu.notification.messagesLabel": "చాట్ సందేశం",
|
||||
"app.submenu.notification.userJoinLabel": "వినియోగదారుడు చేరడo",
|
||||
"app.submenu.notification.userLeaveLabel": "యూజర్ లీవ్",
|
||||
"app.submenu.notification.guestWaitingLabel": "అతిథి నిరీక్షణ ఆమోదం",
|
||||
"app.submenu.audio.micSourceLabel": "మైక్రోఫోన్ మూలం",
|
||||
"app.submenu.audio.speakerSourceLabel": "స్పీకర్ మూలం",
|
||||
@ -370,13 +404,15 @@
|
||||
"app.settings.save-notification.label": "సెట్టింగులు సేవ్ చేయబడ్డాయి",
|
||||
"app.statusNotifier.lowerHands": "చేతులను కిందకి దించారు",
|
||||
"app.statusNotifier.raisedHandsTitle": "చేతులను పైకి ఎత్తారు",
|
||||
"app.statusNotifier.raisedHandDesc": "{0 their వారి చేతులను పైకి లేపారు",
|
||||
"app.statusNotifier.raisedHandDesc": "{0} వారి చేతులను పైకి లేపారు",
|
||||
"app.statusNotifier.raisedHandDescOneUser": "{0} చేయి పైకెత్తింది",
|
||||
"app.statusNotifier.and": "మరియు",
|
||||
"app.switch.onLabel": "ఆన్",
|
||||
"app.switch.offLabel": "ఆఫ్",
|
||||
"app.talkingIndicator.ariaMuteDesc" : "వినియోగదారుని మ్యూట్ చేయడానికి ఎంచుకోండి",
|
||||
"app.talkingIndicator.isTalking" : "{0} మాట్లాడుతున్నారు",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsTalking" : "{0}+ మాట్లాడుతున్నారు",
|
||||
"app.talkingIndicator.moreThanMaxIndicatorsWereTalking" : "{0}+ మాట్లాడుతున్నారు",
|
||||
"app.talkingIndicator.wasTalking" : "{0} మాట్లాడటం మానేసారు",
|
||||
"app.actionsBar.actionsDropdown.actionsLabel": "చర్యలు",
|
||||
"app.actionsBar.actionsDropdown.presentationLabel": "ప్రదర్శనలను నిర్వహించండి",
|
||||
@ -452,6 +488,8 @@
|
||||
"app.audioModal.ariaTitle": "ఆడియో మోడల్లో చేరండి",
|
||||
"app.audioModal.microphoneLabel": "మైక్రోఫోన్",
|
||||
"app.audioModal.listenOnlyLabel": "వినడానికి మాత్రమే",
|
||||
"app.audioModal.microphoneDesc": "మైక్తో ఆడియో కాన్ఫరెన్స్లో చేరండి",
|
||||
"app.audioModal.listenOnlyDesc": "వినడానికి మాత్రమే ఆడియో కాన్ఫరెన్స్లో చేరండి",
|
||||
"app.audioModal.audioChoiceLabel": "మీరు ఆడియోలో ఎలా చేరాలనుకుంటున్నారు?",
|
||||
"app.audioModal.iOSBrowser": "ఆడియో / వీడియో మద్దతు లేదు",
|
||||
"app.audioModal.iOSErrorDescription": "ఈ సమయంలో iOS కోసం Chrome లో ఆడియో మరియు వీడియో మద్దతు లేదు.",
|
||||
@ -477,6 +515,7 @@
|
||||
"app.audioModal.playAudio.arialabel" : "ఆడియో ప్లే చేయండి",
|
||||
"app.audioDial.tipIndicator": "చిట్కా",
|
||||
"app.audioDial.tipMessage": "మిమ్మల్ని మీరు మ్యూట్ / అన్మ్యూట్ చేయడానికి మీ ఫోన్లోని '0' కీని నొక్కండి.",
|
||||
"app.audioModal.connecting": "ఆడియో కనెక్షన్ని ఏర్పాటు చేస్తోంది",
|
||||
"app.audioManager.joinedAudio": "మీరు ఆడియో సమావేశంలో చేరారు",
|
||||
"app.audioManager.joinedEcho": "మీరు ప్రతిధ్వని పరీక్షలో చేరారు",
|
||||
"app.audioManager.leftAudio": "మీరు ఆడియో సమావేశం నుండి వదిలి వెళ్ళారు",
|
||||
@ -488,6 +527,7 @@
|
||||
"app.audioManager.mediaError": "లోపం: మీ మీడియా పరికరాలను పొందడంలో సమస్య ఉంది",
|
||||
"app.audio.joinAudio": "ఆడియోలో చేరండి",
|
||||
"app.audio.leaveAudio": "ఆడియోను వదిలివేయండి",
|
||||
"app.audio.changeAudioDevice": "ఆడియో పరికరాన్ని మార్చండి",
|
||||
"app.audio.enterSessionLabel": "సెషన్ను నమోదు చేయండి",
|
||||
"app.audio.playSoundLabel": "ప్లే సౌండ్",
|
||||
"app.audio.backLabel": "వెనక్కి",
|
||||
@ -532,6 +572,7 @@
|
||||
"app.error.401": "అనధికార",
|
||||
"app.error.403": "మిమ్మల్ని సమావేశం నుండి తొలగించారు",
|
||||
"app.error.404": "దొరకలేదు",
|
||||
"app.error.408": "ధృవీకరణ విఫలమైంది",
|
||||
"app.error.410": "సమావేశం ముగిసింది",
|
||||
"app.error.500": "అయ్యో, ఏదో తప్పు జరిగింది",
|
||||
"app.error.userLoggedOut": "లాగ్ అవుట్ కారణంగా వినియోగదారుకు చెల్లని సెషన్ టోకెన్ ఉంది",
|
||||
@ -553,6 +594,7 @@
|
||||
"app.guest.guestWait": "మీరు సమావేశంలో చేరడానికి మోడరేటర్ ఆమోదించడానికి దయచేసి వేచి ఉండండి.",
|
||||
"app.guest.guestDeny": "సమావేశంలో పాల్గొనడానికి అతిథి నిరాకరించారు.",
|
||||
"app.guest.seatWait": "సమావేశంలో సీటు కోసం వేచి ఉన్న అతిథి.",
|
||||
"app.guest.allow": "అతిథి ఆమోదించబడ్డారు మరియు సమావేశానికి దారి మళ్లించబడ్డారు.",
|
||||
"app.userList.guest.waitingUsers": "వినియోగదారులు వేచి ఉన్నారు",
|
||||
"app.userList.guest.waitingUsersTitle": "వినియోగదారుని నిర్వహణ",
|
||||
"app.userList.guest.optionTitle": "పెండింగ్ వినియోగదారులను రివ్యు చేయండి",
|
||||
@ -584,6 +626,7 @@
|
||||
"app.notification.recordingPaused": "ఈ సెషన్ ఇకపై రికార్డ్ చేయబడదు",
|
||||
"app.notification.recordingAriaLabel": "రికార్డ్ చేసిన సమయం",
|
||||
"app.notification.userJoinPushAlert": "{0 } సెషన్లో చేరారు",
|
||||
"app.notification.userLeavePushAlert": "{0} సెషన్ నుండి వెళ్లిపోయారు",
|
||||
"app.submenu.notification.raiseHandLabel": "చేయి పైకెత్తండి",
|
||||
"app.shortcut-help.title": "యాక్సెస్ కీలు అందుబాటులో లేవు",
|
||||
"app.shortcut-help.accessKeyNotAvailable": "యాక్సెస్ కీలు అందుబాటులో లేవు",
|
||||
@ -627,14 +670,25 @@
|
||||
"app.guest-policy.button.askModerator": "మోడరేటర్ను అడగండి",
|
||||
"app.guest-policy.button.alwaysAccept": "ఎల్లప్పుడూ అంగీకరించండి",
|
||||
"app.guest-policy.button.alwaysDeny": "ఎల్లప్పుడూ తిరస్కరించండి",
|
||||
"app.guest-policy.policyBtnDesc": "మీటింగ్ గెస్ట్ పాలసీని సెట్ చేయండి",
|
||||
"app.connection-status.ariaTitle": "కనెక్షన్ స్థితి మోడల్",
|
||||
"app.connection-status.title": "కనెక్షన్ స్థితి",
|
||||
"app.connection-status.description": "వినియోగదారుల కనెక్షన్ స్థితిని చూడండి",
|
||||
"app.connection-status.empty": "ప్రస్తుతం నివేదించబడిన కనెక్షన్ సమస్యలు లేవు",
|
||||
"app.connection-status.more": "మరిన్ని",
|
||||
"app.connection-status.copy": "నెట్వర్క్ డేటాను కాపీ చేయండి",
|
||||
"app.connection-status.copied": "కాపీ చేయబడింది!",
|
||||
"app.connection-status.jitter": "గందరగోళం",
|
||||
"app.connection-status.label": "కనెక్షన్ స్థితి",
|
||||
"app.connection-status.no": "లేదు",
|
||||
"app.connection-status.notification": "మీ కనెక్షన్లో నష్టం కనుగొనబడింది",
|
||||
"app.connection-status.offline": "ఆఫ్లైన్",
|
||||
"app.connection-status.lostPackets": "కోల్పోయిన ప్యాకెట్లు",
|
||||
"app.connection-status.usingTurn": "TURN ని ఉపయోగిస్తోంది",
|
||||
"app.connection-status.yes": "అవును",
|
||||
"app.learning-dashboard.label": "లెర్నింగ్ డాష్బోర్డ్",
|
||||
"app.learning-dashboard.description": "వినియోగదారుల కార్యకలాపాలతో డ్యాష్బోర్డ్ని తెరవండి",
|
||||
"app.learning-dashboard.clickHereToOpen": "లెర్నింగ్ డాష్బోర్డ్ను తెరవండి",
|
||||
"app.recording.startTitle": "రికార్డింగ్ ప్రారంభించు",
|
||||
"app.recording.stopTitle": "రికార్డింగ్ను పాజ్ చేయి",
|
||||
"app.recording.resumeTitle": "రికార్డింగ్ను తిరిగి ప్రారంభించు",
|
||||
@ -656,6 +710,8 @@
|
||||
"app.videoPreview.webcamOptionLabel": "వెబ్క్యామ్ను ఎంచుకోండి",
|
||||
"app.videoPreview.webcamPreviewLabel": "వెబ్క్యామ్ ప్రివ్యూ",
|
||||
"app.videoPreview.webcamSettingsTitle": "వెబ్క్యామ్ సెట్టింగులు",
|
||||
"app.videoPreview.webcamVirtualBackgroundLabel": "వర్చువల్ బ్యాక్గ్రౌండ్ సెట్టింగులు",
|
||||
"app.videoPreview.webcamVirtualBackgroundDisabledLabel": "ఈ పరికరం వర్చువల్ బ్యాక్గ్రౌండ్లకు మద్దతు ఇవ్వదు",
|
||||
"app.videoPreview.webcamNotFoundLabel": "వెబ్క్యామ్ కనుగొనబడలేదు",
|
||||
"app.videoPreview.profileNotFoundLabel": "కెమెరా ప్రొఫైల్ కు మద్దతు లేదు",
|
||||
"app.video.joinVideo": "వెబ్క్యామ్ను షేర్ చేయండి",
|
||||
@ -675,6 +731,7 @@
|
||||
"app.video.notReadableError": "వెబ్క్యామ్ వీడియో పొందలేకపోయాము. దయచేసి మరొక ప్రోగ్రామ్ ,వెబ్క్యామ్ను ఉపయోగించడం లేదని నిర్ధారించుకోండి",
|
||||
"app.video.timeoutError": "బ్రౌజర్ సకాలంలో స్పందించలేదు.",
|
||||
"app.video.genericError": "ഉപകരണത്തിൽ ഒരു അജ്ഞാത പിശക് സംഭവിച്ചു (പിശക് {0})",
|
||||
"app.video.mediaTimedOutError": "మీ వెబ్క్యామ్ స్ట్రీమ్కు అంతరాయం ఏర్పడింది. దాన్ని మళ్లీ షేర్ చేయడానికి ప్రయత్నించండి",
|
||||
"app.video.mediaFlowTimeout1020": "మీడియా సర్వర్కు చేరుకోలేదు (లోపం 1020)",
|
||||
"app.video.suggestWebcamLock": "వీక్షకుల వెబ్క్యామ్కు లాక్ సెట్టింగ్ను అమలు చేయాలా?",
|
||||
"app.video.suggestWebcamLockReason": "(ఇది సమావేశం యొక్క స్థిరత్వాన్ని మెరుగుపరుస్తుంది)",
|
||||
@ -689,9 +746,16 @@
|
||||
"app.video.videoMenuDesc": "వీడియో మెను డ్రాప్డౌన్ తెరవండి",
|
||||
"app.video.pagination.prevPage": "മുമ്പത്തെ വീഡിയോകൾ കാണുക",
|
||||
"app.video.pagination.nextPage": "അടുത്ത വീഡിയോകൾ കാണുക",
|
||||
"app.video.clientDisconnected": "കണക്ഷൻ പ്രശ്നങ്ങൾ കാരണം വെബ്ക്യാം പങ്കിടാൻ കഴിയില്ല",
|
||||
"app.video.clientDisconnected": "కనెక్షన్ సమస్యల కారణంగా వెబ్క్యామ్ షేర్ చేయబడదు",
|
||||
"app.video.virtualBackground.none": "ఏదీ లేదు",
|
||||
"app.video.virtualBackground.blur": "అస్పష్టత",
|
||||
"app.video.virtualBackground.genericError": "కెమెరా ప్రభావాన్ని వర్తింపజేయడంలో విఫలమైంది. మళ్లీ ప్రయత్నించండి.",
|
||||
"app.video.virtualBackground.camBgAriaDesc": "వెబ్క్యామ్ వర్చువల్ బ్యాక్ గ్రౌండ్ {0} కి సెట్ చేస్తుంది",
|
||||
"app.video.dropZoneLabel": "ఇక్కడ డ్రాప్ చేయండి",
|
||||
"app.fullscreenButton.label": "పూర్తి స్క్రీన్{0} చేయండి",
|
||||
"app.fullscreenUndoButton.label": "Screen 0} പൂർണ്ണസ്ക്രീൻ പഴയപടിയാക്കുക",
|
||||
"app.switchButton.expandLabel": "స్క్రీన్ షేర్ వీడియోను విస్తరించండి",
|
||||
"app.switchButton.shrinkLabel": "స్క్రీన్ షేర్ వీడియోను కుదించండి",
|
||||
"app.sfu.mediaServerConnectionError2000": "మీడియా సర్వర్కు కనెక్ట్ చేయడం సాధ్యం కాలేదు (లోపం 2000)",
|
||||
"app.sfu.mediaServerOffline2001": "మీడియా సర్వర్ ఆఫ్లైన్లో ఉంది. దయచేసి తరువాత మళ్ళీ ప్రయత్నించండి (లోపం 2001)",
|
||||
"app.sfu.mediaServerNoResources2002": "మీడియా సర్వర్కు అందుబాటులో ఉన్న వనరులు లేవు (లోపం 2002)",
|
||||
@ -735,13 +799,14 @@
|
||||
"app.whiteboard.toolbar.palmRejectionOn": "ഈന്തപ്പന നിരസിക്കൽ ഓണാക്കുക",
|
||||
"app.whiteboard.toolbar.palmRejectionOff": "ഈന്തപ്പന നിരസിക്കൽ ഓഫാക്കുക",
|
||||
"app.whiteboard.toolbar.fontSize": "ఫాంట్ పరిమాణ జాబితా",
|
||||
"app.whiteboard.toolbarAriaLabel": "ప్రదర్శన సాధనాలు",
|
||||
"app.feedback.title": "మీరు సమావేశం నుండి లాగ్ అవుట్ అయ్యారు",
|
||||
"app.feedback.subtitle": "బిగ్బ్లూబటన్ తో మీ అనుభవం గురించి వినడానికి మేము ఇష్టపడతాము (మీ ఇష్ట ప్రకారం ) .",
|
||||
"app.feedback.textarea": "బిగ్బ్లూబటన్ను ఎలా మెరుగుపరుస్తాము?",
|
||||
"app.feedback.sendFeedback": "అభిప్రాయాన్ని పంపండి",
|
||||
"app.feedback.sendFeedbackDesc": "అభిప్రాయాన్ని పంపండి మరియు సమావేశాన్ని వదిలివేయండి",
|
||||
"app.videoDock.webcamMirrorLabel": "കണ്ണാടി",
|
||||
"app.videoDock.webcamMirrorDesc": "തിരഞ്ഞെടുത്ത വെബ്ക്യാം മിറർ ചെയ്യുക",
|
||||
"app.videoDock.webcamMirrorDesc": "ఎంచుకున్న వెబ్క్యామ్ను ప్రతిబింబిస్తుంది",
|
||||
"app.videoDock.webcamFocusLabel": "దృష్టి",
|
||||
"app.videoDock.webcamFocusDesc": "ఎంచుకున్న వెబ్క్యామ్పై దృష్టి పెట్టండి",
|
||||
"app.videoDock.webcamUnfocusLabel": "దృష్టి లేని",
|
||||
@ -753,7 +818,9 @@
|
||||
"app.createBreakoutRoom.title": "బ్రేక్అవుట్ రూములు",
|
||||
"app.createBreakoutRoom.ariaTitle": "బ్రేక్అవుట్ గదులను దాచండి",
|
||||
"app.createBreakoutRoom.breakoutRoomLabel": "బ్రేక్అవుట్ రూములు {0}",
|
||||
"app.createBreakoutRoom.askToJoin": "చేరమని అడగండి",
|
||||
"app.createBreakoutRoom.generatingURL": "URL ను సృష్టిస్తోంది",
|
||||
"app.createBreakoutRoom.generatingURLMessage": "మేము ఎంచుకున్న బ్రేక్అవుట్ రూమ్ కోసం జాయిన్ URL ని రూపొందిస్తున్నాము. ఇది కొన్ని సెకన్ల సమయం పట్టవచ్చు...",
|
||||
"app.createBreakoutRoom.duration": "వ్యవధి {0}",
|
||||
"app.createBreakoutRoom.room": "గది {0}",
|
||||
"app.createBreakoutRoom.notAssigned": "కేటాయించబడలేదు ({0})",
|
||||
@ -766,6 +833,7 @@
|
||||
"app.createBreakoutRoom.numberOfRooms": "గదుల సంఖ్య",
|
||||
"app.createBreakoutRoom.durationInMinutes": "వ్యవధి (నిమిషాలు)",
|
||||
"app.createBreakoutRoom.randomlyAssign": "అస్తవ్యస్తంగా కేటాయించండి",
|
||||
"app.createBreakoutRoom.randomlyAssignDesc": "వినియోగదారులను రేండం గా బ్రేక్అవుట్ రూమ్లకు కేటాయిస్తుంది",
|
||||
"app.createBreakoutRoom.endAllBreakouts": "అన్ని బ్రేక్అవుట్ గదులను ముగించండి",
|
||||
"app.createBreakoutRoom.roomName": "{0} (గది - {1})",
|
||||
"app.createBreakoutRoom.doneLabel": "పూర్తి అయ్యింది",
|
||||
@ -775,9 +843,17 @@
|
||||
"app.createBreakoutRoom.addParticipantLabel": "+ పాల్గొనేవారిని జోడించండి",
|
||||
"app.createBreakoutRoom.freeJoin": "వినియోగదారులు చేరడానికి ఒక బ్రేక్అవుట్ గది ఎంచుకొవడానికి అనుమతి ని ఇవ్వండి",
|
||||
"app.createBreakoutRoom.leastOneWarnBreakout": "మీరు కనీసం ఒక వినియోగదారుడ్ని బ్రేక్అవుట్ గదిలో ఉంచాలి.",
|
||||
"app.createBreakoutRoom.minimumDurationWarnBreakout": "బ్రేక్అవుట్ గదికి కనీస వ్యవధి {0} నిమిషాలు.",
|
||||
"app.createBreakoutRoom.modalDesc": "చిట్కా: మీరు ఒక నిర్దిష్ట బ్రేక్అవుట్ గదికి కేటాయించడానికి వినియోగదారు పేరును డ్రాగ్ మరియు డ్రాప్ చేయండి.",
|
||||
"app.createBreakoutRoom.roomTime": "{0}నిమిషాలు",
|
||||
"app.createBreakoutRoom.numberOfRoomsError": "గదుల సంఖ్య చెల్లదు.",
|
||||
"app.createBreakoutRoom.duplicatedRoomNameError": "గది పేరు నకిలీ చేయబడదు.",
|
||||
"app.createBreakoutRoom.emptyRoomNameError": "గది పేరు ఖాళీగా ఉండకూడదు.",
|
||||
"app.createBreakoutRoom.extendTimeInMinutes": "పొడిగించే సమయం (నిమిషాలు)",
|
||||
"app.createBreakoutRoom.extendTimeLabel": "పొడిగించు",
|
||||
"app.createBreakoutRoom.extendTimeCancel": "రద్దు చేయండి",
|
||||
"app.createBreakoutRoom.extendTimeHigherThanMeetingTimeError": "బ్రేక్అవుట్ గదుల వ్యవధి సమావేశం మిగిలిన సమయాన్ని మించకూడదు.",
|
||||
"app.createBreakoutRoom.roomNameInputDesc": "బ్రేక్అవుట్ రూమ్ పేరును అప్డేట్ చేస్తుంది",
|
||||
"app.externalVideo.start": "కొత్త వీడియోను షేర్ చేయండి",
|
||||
"app.externalVideo.title": "బాహ్య వీడియోను షేర్ చేయండి",
|
||||
"app.externalVideo.input": "బాహ్య వీడియో URL",
|
||||
@ -785,6 +861,7 @@
|
||||
"app.externalVideo.urlError": "ఈ వీడియో URL కి మద్దతు లేదు",
|
||||
"app.externalVideo.close": "మూసివేయి",
|
||||
"app.externalVideo.autoPlayWarning": "మీడియా సమకాలీకరణను ప్రారంభించడానికి వీడియోను ప్లే చేయండి",
|
||||
"app.externalVideo.refreshLabel": "వీడియో ప్లేయర్ని రిఫ్రెష్ చేయండి",
|
||||
"app.externalVideo.noteLabel": "గమనిక: షేర్ చేసిన బాహ్య వీడియోలు రికార్డింగ్లో కనిపించవు. యూట్యూబ్, విమియో, ఇన్స్ట్రక్చర్ మీడియా, ట్విచ్, డైలీమోషన్ మరియు మీడియా ఫైల్ URL లకు (ఉ.దా: https://example.com/xy.mp4) మద్దతు ఉంది.",
|
||||
"app.actionsBar.actionsDropdown.shareExternalVideo": "బాహ్య వీడియోను షేర్ చేయండి",
|
||||
"app.actionsBar.actionsDropdown.stopShareExternalVideo": "బాహ్య వీడియోను షేర్ చేయడం ఆపివేయండి",
|
||||
@ -796,7 +873,71 @@
|
||||
"app.debugWindow.form.userAgentLabel": "ഉപയോക്തൃ ഏജൻറ്",
|
||||
"app.debugWindow.form.button.copy": "പകർത്തുക",
|
||||
"app.debugWindow.form.enableAutoarrangeLayoutLabel": "യാന്ത്രിക ക്രമീകരണ ലേ Layout ട്ട് പ്രവർത്തനക്ഷമമാക്കുക",
|
||||
"app.debugWindow.form.enableAutoarrangeLayoutDescription": "(നിങ്ങൾ വെബ്ക്യാം ഏരിയ വലിച്ചിടുകയോ വലുപ്പം മാറ്റുകയോ ചെയ്താൽ ഇത് പ്രവർത്തനരഹിതമാകും)"
|
||||
"app.debugWindow.form.enableAutoarrangeLayoutDescription": "(మీరు వెబ్క్యామ్ల ప్రాంతాన్ని లాగడం లేదా పరిమాణం మార్చడం ద్వారా ఇది నిలిపివేయబడుతుంది)",
|
||||
"app.debugWindow.form.chatLoggerLabel": "చాట్ లాగర్ లెవల్స్ ను పరీక్షించండి",
|
||||
"app.debugWindow.form.button.apply": "అమలు చేయి",
|
||||
"app.layout.style.custom": "వాడుక",
|
||||
"app.layout.style.smart": "స్మార్ట్ లేఅవుట్",
|
||||
"app.layout.style.presentationFocus": "ప్రదర్శనపై దృష్టి పెట్టండి",
|
||||
"app.layout.style.videoFocus": "వీడియోపై దృష్టి పెట్టండి",
|
||||
"app.layout.style.presentationFocusPush": "ప్రెజెంటేషన్పై దృష్టి పెట్టండి (అందరికీ లేఅవుట్ను నెట్టండి)",
|
||||
"app.layout.style.videoFocusPush": "వీడియోపై దృష్టి పెట్టండి (అందరికీ లేఅవుట్ను పుష్ చేయండి)",
|
||||
"playback.button.about.aria": "గురించి",
|
||||
"playback.button.clear.aria": "శోధనను క్లియర్ చేయండి",
|
||||
"playback.button.close.aria": "మోడల్ను మూసివేయండి",
|
||||
"playback.button.fullscreen.aria": "పూర్తి స్క్రీన్ విషయము",
|
||||
"playback.button.restore.aria": "కంటెంట్ను పునరుద్ధరించండి",
|
||||
"playback.button.search.aria": "వెతకండి",
|
||||
"playback.button.section.aria": "పక్క విభాగం",
|
||||
"playback.button.swap.aria": "కంటెంట్ను మార్చుకోండి",
|
||||
"playback.error.wrapper.aria": "లోపం ప్రాంతం",
|
||||
"playback.loader.wrapper.aria": "లోడ్ చేసే ప్రాంతం",
|
||||
"playback.player.wrapper.aria": "ప్లేయర్ ప్రాంతం",
|
||||
"playback.player.chat.message.poll.name": "పోల్ ఫలితం",
|
||||
"playback.player.chat.message.poll.question": "ప్రశ్న",
|
||||
"playback.player.chat.message.poll.options": "ఎంపికలు",
|
||||
"playback.player.chat.message.poll.option.yes": "అవును",
|
||||
"playback.player.chat.message.poll.option.no": "కాదు",
|
||||
"playback.player.chat.message.poll.option.abstention": "తిరస్కరించు",
|
||||
"playback.player.chat.message.poll.option.true": "ఒప్పు",
|
||||
"playback.player.chat.message.poll.option.false": "తప్పు",
|
||||
"playback.player.chat.message.externalVideo.name": "బాహ్య వీడియో ",
|
||||
"playback.player.chat.wrapper.aria": "కబుర్లుప్రదేశం",
|
||||
"playback.player.notes.wrapper.aria": "నోట్స్ ప్రాంతం",
|
||||
"playback.player.presentation.wrapper.aria": "ప్రదర్శన ప్రాంతం",
|
||||
"playback.player.screenshare.wrapper.aria": "స్క్రీన్ షేర్ ప్రాంతం",
|
||||
"playback.player.search.modal.title": "వెతకండి",
|
||||
"playback.player.search.modal.subtitle": "ప్రదర్శన స్లయిడ్ల కంటెంట్ను కనుగొనండి",
|
||||
"playback.player.thumbnails.wrapper.aria": "సూక్ష్మచిత్రాల ప్రాంతం",
|
||||
"playback.player.video.wrapper.aria": "వీడియో ప్రాంతం",
|
||||
"app.learningDashboard.dashboardTitle": "చాట్ ప్రదేశం",
|
||||
"app.learningDashboard.user": "వినియోగదారుడు ",
|
||||
"app.learningDashboard.indicators.meetingStatusEnded": "ముగిసింది",
|
||||
"app.learningDashboard.indicators.meetingStatusActive": "యాక్టివ్",
|
||||
"app.learningDashboard.indicators.usersOnline": "క్రియాశీల వినియోగదారులు",
|
||||
"app.learningDashboard.indicators.usersTotal": "మొత్తం వినియోగదారుల సంఖ్య",
|
||||
"app.learningDashboard.indicators.polls": "పోల్స్",
|
||||
"app.learningDashboard.indicators.raiseHand": "చేయి పైకెత్తండి",
|
||||
"app.learningDashboard.indicators.activityScore": "కార్యాచరణ స్కోరు",
|
||||
"app.learningDashboard.indicators.duration": "వ్యవధి",
|
||||
"app.learningDashboard.usersTable.title": "సారాంశం",
|
||||
"app.learningDashboard.usersTable.colOnline": "ఆన్లైన్ సమయం",
|
||||
"app.learningDashboard.usersTable.colTalk": "మాట్లాడు సమయం",
|
||||
"app.learningDashboard.usersTable.colWebcam": "వెబ్క్యామ్ సమయం",
|
||||
"app.learningDashboard.usersTable.colMessages": "సందేశాలు",
|
||||
"app.learningDashboard.usersTable.colEmojis": "ఎమోజీలు",
|
||||
"app.learningDashboard.usersTable.colRaiseHands": "చేతులు పైకెత్తండి",
|
||||
"app.learningDashboard.usersTable.colActivityScore": "కార్యాచరణ స్కోరు",
|
||||
"app.learningDashboard.usersTable.colStatus": "స్థితి",
|
||||
"app.learningDashboard.usersTable.userStatusOnline": "ఆన్లైన్",
|
||||
"app.learningDashboard.usersTable.userStatusOffline": "ఆఫ్లైన్",
|
||||
"app.learningDashboard.usersTable.noUsers": "ఇంకా వినియోగదారులు లేరు",
|
||||
"app.learningDashboard.pollsTable.title": "పోలింగ్",
|
||||
"app.learningDashboard.pollsTable.anonymousAnswer": "అనామక పోల్ (చివరి వరుసలో సమాధానాలు)",
|
||||
"app.learningDashboard.pollsTable.anonymousRowName": "అనామక",
|
||||
"app.learningDashboard.statusTimelineTable.title": "స్థితి కాలక్రమం",
|
||||
"app.learningDashboard.errors.invalidToken": "సెషన్ టోకెన్ చెల్లదు",
|
||||
"app.learningDashboard.errors.dataUnavailable": "డేటా ఇకపై అందుబాటులో ఉండదు"
|
||||
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
"app.chat.dropdown.save": "Kaydet",
|
||||
"app.chat.label": "Sohbet",
|
||||
"app.chat.offline": "Çevrimdışı",
|
||||
"app.chat.pollResult": "Anket sonuçları",
|
||||
"app.chat.pollResult": "Anket Sonuçları",
|
||||
"app.chat.emptyLogLabel": "Sohbet günlüğü boş",
|
||||
"app.chat.clearPublicChatMessage": "Herkese açık sohbet geçmişi sorumlu tarafından temizlendi",
|
||||
"app.chat.multi.typing": "Birkaç kullanıcı yazıyor",
|
||||
@ -48,6 +48,8 @@
|
||||
"app.captions.pad.dictationStop": "Dikteyi durdur",
|
||||
"app.captions.pad.dictationOnDesc": " Konuşma tanımayı açar",
|
||||
"app.captions.pad.dictationOffDesc": " Konuşma tanımayı kapatır",
|
||||
"app.textInput.sendLabel": "Gönder",
|
||||
"app.title.defaultViewLabel": "Varsayılan sunum görünümü",
|
||||
"app.note.title": "Paylaşılan Notlar",
|
||||
"app.note.label": "Not",
|
||||
"app.note.hideNoteLabel": "Notu gizle",
|
||||
@ -67,8 +69,11 @@
|
||||
"app.userList.byModerator": "(Sorumlu) tarafından",
|
||||
"app.userList.label": "Kullanıcı listesi",
|
||||
"app.userList.toggleCompactView.label": "Basit görünüm kipini aç/kapat",
|
||||
"app.userList.mobile": "Mobil",
|
||||
"app.userList.guest": "Konuk",
|
||||
"app.userList.sharingWebcam": "Web kamerası",
|
||||
"app.userList.menuTitleContext": "Kullanılabilecek seçenekler",
|
||||
"app.userList.chatListItem.unreadSingular": "Bir yeni ileti",
|
||||
"app.userList.menu.chat.label": "Özel sohbet başlat",
|
||||
"app.userList.menu.clearStatus.label": "Durumu temizle",
|
||||
"app.userList.menu.removeUser.label": "Kullanıcıyı sil",
|
||||
@ -213,6 +218,7 @@
|
||||
"app.poll.customPlaceholder": "Anket seçeneği ekle",
|
||||
"app.poll.noPresentationSelected": "Herhangi bir sunum seçilmemiş! Lütfen bir sunum seçin.",
|
||||
"app.poll.clickHereToSelect": "Seçmek için buraya tıklayın",
|
||||
"app.poll.optionDelete.label" : "Sil",
|
||||
"app.poll.t": "Doğru",
|
||||
"app.poll.f": "Yanlış",
|
||||
"app.poll.tf": "Doğru / Yanlış",
|
||||
@ -293,6 +299,7 @@
|
||||
"app.submenu.application.languageLabel": "Uygulama Dili",
|
||||
"app.submenu.application.languageOptionLabel": "Dil seçin",
|
||||
"app.submenu.application.noLocaleOptionLabel": "Etkin bir dil bulunamadı",
|
||||
"app.submenu.application.paginationEnabledLabel": "Video sayfalama",
|
||||
"app.submenu.notification.SectionTitle": "Bildirimler",
|
||||
"app.submenu.notification.Desc": "Nasıl ve neye bildirileceğinizi tanımlayın.",
|
||||
"app.submenu.notification.audioAlertLabel": "Sesli Uyarılar",
|
||||
|
@ -18,7 +18,7 @@
|
||||
"app.chat.dropdown.copy": "Kopyala",
|
||||
"app.chat.dropdown.save": "Kaydet",
|
||||
"app.chat.label": "Sohbet",
|
||||
"app.chat.offline": "Çevrimdışı",
|
||||
"app.chat.offline": "Çevrim Dışı",
|
||||
"app.chat.pollResult": "Anket sonuçları",
|
||||
"app.chat.emptyLogLabel": "Sohbet sistem kayıtları boş",
|
||||
"app.chat.clearPublicChatMessage": "Genel sohbet geçmişi moderatör tarafından temizlendi",
|
||||
@ -87,7 +87,7 @@
|
||||
"app.userList.menu.removeConfirmation.label": "({0}) kullanıcısını kaldır",
|
||||
"app.userlist.menu.removeConfirmation.desc": "Bu kullanıcının oturuma yeniden katılması engellensin",
|
||||
"app.userList.menu.muteUserAudio.label": "Kullanıcıyı sustur",
|
||||
"app.userList.menu.unmuteUserAudio.label": "Kullanıcıyı konuştur",
|
||||
"app.userList.menu.unmuteUserAudio.label": "Kullanıcı Sesini Aç",
|
||||
"app.userList.menu.giveWhiteboardAccess.label" : "Tahta Erişimi Verin",
|
||||
"app.userList.menu.removeWhiteboardAccess.label": "Tahta Erişimini Kaldırın",
|
||||
"app.userList.userAriaLabel": "{0} {1} {2} Durum {3}",
|
||||
@ -104,7 +104,7 @@
|
||||
"app.userList.userOptions.clearAllDesc": "Tüm durum simgelerini kullanıcılardan temizler",
|
||||
"app.userList.userOptions.muteAllExceptPresenterLabel": "Sunucu Hariç Tümünü Sustur",
|
||||
"app.userList.userOptions.muteAllExceptPresenterDesc": "Toplantıda sunum yapan kişi dışındaki tüm kullanıcıları susturur",
|
||||
"app.userList.userOptions.unmuteAllLabel": "Toplantı sesini kapatma",
|
||||
"app.userList.userOptions.unmuteAllLabel": "Toplantı Sesini Aç",
|
||||
"app.userList.userOptions.unmuteAllDesc": "Toplantı sesini aç",
|
||||
"app.userList.userOptions.lockViewersLabel": "Katılımcıları Kilitle",
|
||||
"app.userList.userOptions.lockViewersDesc": "Toplantı katılımcıları için bazı işlevleri kilitle",
|
||||
@ -350,7 +350,7 @@
|
||||
"app.about.dismissDesc": "Kullanıcı bilgilerini kapat",
|
||||
"app.actionsBar.changeStatusLabel": "Durumu değiştir",
|
||||
"app.actionsBar.muteLabel": "Sustur",
|
||||
"app.actionsBar.unmuteLabel": "Konuştur",
|
||||
"app.actionsBar.unmuteLabel": "Sesi Aç",
|
||||
"app.actionsBar.camOffLabel": "Kamera kapalı",
|
||||
"app.actionsBar.raiseLabel": "El Kaldır",
|
||||
"app.actionsBar.label": "Eylemler çubuğu",
|
||||
@ -404,7 +404,7 @@
|
||||
"app.settings.save-notification.label": "Ayarlar kaydedildi",
|
||||
"app.statusNotifier.lowerHands": "Elleri indir",
|
||||
"app.statusNotifier.raisedHandsTitle": "Kalkık eller",
|
||||
"app.statusNotifier.raisedHandDesc": "{0} kişi ellerini kaldırdı",
|
||||
"app.statusNotifier.raisedHandDesc": "{0} kişi ellini kaldırdı",
|
||||
"app.statusNotifier.raisedHandDescOneUser": "{0} el kaldırma",
|
||||
"app.statusNotifier.and": "ve",
|
||||
"app.switch.onLabel": "AÇIK",
|
||||
@ -616,7 +616,7 @@
|
||||
"app.toast.clearedEmoji.label": "Emoji durumu temizlendi",
|
||||
"app.toast.setEmoji.label": "Emoji durumu {0} olarak ayarlandı",
|
||||
"app.toast.meetingMuteOn.label": "Tüm kullanıcılar için ses kapatıldı",
|
||||
"app.toast.meetingMuteOff.label": "Toplantı sesini kapatma kapatıldı",
|
||||
"app.toast.meetingMuteOff.label": "Toplantı sesi açıldı.",
|
||||
"app.toast.setEmoji.raiseHand": "Elinizi kaldırdınız",
|
||||
"app.toast.setEmoji.lowerHand": "Elinizi indirdiniz",
|
||||
"app.notification.recordingStart": "Bu oturum şu anda kaydediliyor",
|
||||
@ -634,7 +634,7 @@
|
||||
"app.shortcut-help.closeDesc": "Klavye kısayolları modunu kapatır",
|
||||
"app.shortcut-help.openOptions": "Seçenekleri Aç",
|
||||
"app.shortcut-help.toggleUserList": "Kullanıcı Listesine Geç",
|
||||
"app.shortcut-help.toggleMute": "Sustur / Konuştur",
|
||||
"app.shortcut-help.toggleMute": "Sessiz / Sesi Aç",
|
||||
"app.shortcut-help.togglePublicChat": "Genel Sohbeti değiştir (Kullanıcı listesi açık olmalıdır)",
|
||||
"app.shortcut-help.hidePrivateChat": "Özel mesajı gizle",
|
||||
"app.shortcut-help.closePrivateChat": "Özel mesajı kapat",
|
||||
@ -663,7 +663,7 @@
|
||||
"app.lock-viewers.locked": "Kilitli",
|
||||
"app.lock-viewers.unlocked": "Açık",
|
||||
"app.guest-policy.ariaTitle": "Misafir politikası ayarları modeli",
|
||||
"app.guest-policy.title": "Misafir politikası",
|
||||
"app.guest-policy.title": "Misafir Politikası",
|
||||
"app.guest-policy.description": "Toplantı misafir politika ayarını değiştirin",
|
||||
"app.guest-policy.button.askModerator": "Moderatöre sorun",
|
||||
"app.guest-policy.button.alwaysAccept": "Her zaman kabul edin",
|
||||
@ -680,7 +680,7 @@
|
||||
"app.connection-status.label": "Bağlantı Durumu",
|
||||
"app.connection-status.no": "Hayır",
|
||||
"app.connection-status.notification": "Bağlantınızda kayıp tespit edildi",
|
||||
"app.connection-status.offline": "çevrimdışı",
|
||||
"app.connection-status.offline": "çevrim dışı",
|
||||
"app.connection-status.lostPackets": "Kayıp Paketler",
|
||||
"app.connection-status.usingTurn": "TURN Kullanımı",
|
||||
"app.connection-status.yes": "Evet",
|
||||
@ -755,7 +755,7 @@
|
||||
"app.switchButton.expandLabel": "Ekran paylaşım videosunu genişlet",
|
||||
"app.switchButton.shrinkLabel": "Ekran paylaşım videosunu küçült",
|
||||
"app.sfu.mediaServerConnectionError2000": "Medya sunucusuna ulaşılamıyor (hata 2000)",
|
||||
"app.sfu.mediaServerOffline2001": "Medya sunucusu çevrimdışı. Lütfen daha sonra tekrar deneyin (hata 2001)",
|
||||
"app.sfu.mediaServerOffline2001": "Medya sunucusu çevrim dışı. Lütfen daha sonra tekrar deneyin (hata 2001)",
|
||||
"app.sfu.mediaServerNoResources2002": "Medya sunucunun kullanım için uygun kaynağı yok (hata 2002)",
|
||||
"app.sfu.mediaServerRequestTimeout2003": "Medya sunucu istekleri zaman aşımına uğruyor (hata 2003)",
|
||||
"app.sfu.serverIceGatheringFailed2021": "Medya sunucu bağlantı parametrelerini alamıyor (ICE hatası 2021)",
|
||||
@ -794,8 +794,8 @@
|
||||
"app.whiteboard.toolbar.clear": "Tüm Ek Açıklamaları Temizle",
|
||||
"app.whiteboard.toolbar.multiUserOn": "Çoklu kullanıcı modunu aç",
|
||||
"app.whiteboard.toolbar.multiUserOff": "Çoklu kullanıcı modunu kapat",
|
||||
"app.whiteboard.toolbar.palmRejectionOn": "Reddini açın",
|
||||
"app.whiteboard.toolbar.palmRejectionOff": "Reddini kapatın",
|
||||
"app.whiteboard.toolbar.palmRejectionOn": "Avuç içi reddetmeyi aç",
|
||||
"app.whiteboard.toolbar.palmRejectionOff": "Avuç içi reddetmeyi kapat",
|
||||
"app.whiteboard.toolbar.fontSize": "Yazı tipi boyutu listesi",
|
||||
"app.whiteboard.toolbarAriaLabel": "Sunum araçları",
|
||||
"app.feedback.title": "Konferanstan ayrıldınız",
|
||||
@ -816,6 +816,7 @@
|
||||
"app.createBreakoutRoom.title": "Çalışma Odaları",
|
||||
"app.createBreakoutRoom.ariaTitle": "Çalışma Odalarını Gizle",
|
||||
"app.createBreakoutRoom.breakoutRoomLabel": "Çalışma Odası {0}",
|
||||
"app.createBreakoutRoom.askToJoin": "Katılmayı İste",
|
||||
"app.createBreakoutRoom.generatingURL": "URL oluşturuluyor",
|
||||
"app.createBreakoutRoom.generatingURLMessage": "Seçilen çalışma odası için bir katılım URL'si oluşturuyoruz. Birkaç saniye sürebilir...",
|
||||
"app.createBreakoutRoom.duration": "Süre {0}",
|
||||
@ -918,22 +919,22 @@
|
||||
"app.learningDashboard.indicators.activityScore": "Etkinlik Puanı",
|
||||
"app.learningDashboard.indicators.duration": "Süre",
|
||||
"app.learningDashboard.usersTable.title": "Genel bakış",
|
||||
"app.learningDashboard.usersTable.colOnline": "Online süresi",
|
||||
"app.learningDashboard.usersTable.colTalk": "Konuşma süresi",
|
||||
"app.learningDashboard.usersTable.colWebcam": "Webkamera süresi",
|
||||
"app.learningDashboard.usersTable.colOnline": "Çevrim İçi Süre",
|
||||
"app.learningDashboard.usersTable.colTalk": "Konuşma Süresi",
|
||||
"app.learningDashboard.usersTable.colWebcam": "Web Kamera Süresi",
|
||||
"app.learningDashboard.usersTable.colMessages": "Mesaj",
|
||||
"app.learningDashboard.usersTable.colEmojis": "Emojiler",
|
||||
"app.learningDashboard.usersTable.colRaiseHands": "El Kaldır",
|
||||
"app.learningDashboard.usersTable.colActivityScore": "Etkinlik skoru",
|
||||
"app.learningDashboard.usersTable.colActivityScore": "Etkinlik Puanı",
|
||||
"app.learningDashboard.usersTable.colStatus": "Durum",
|
||||
"app.learningDashboard.usersTable.userStatusOnline": "Çevrimiçi",
|
||||
"app.learningDashboard.usersTable.userStatusOffline": "Çevrimdışı",
|
||||
"app.learningDashboard.usersTable.userStatusOffline": "Çevrim Dışı",
|
||||
"app.learningDashboard.usersTable.noUsers": "Henüz kullanıcı yok",
|
||||
"app.learningDashboard.pollsTable.title": "Anket",
|
||||
"app.learningDashboard.pollsTable.anonymousAnswer": "İsimsiz Anket (cevaplar son satırda)",
|
||||
"app.learningDashboard.pollsTable.anonymousRowName": "İsimsiz",
|
||||
"app.learningDashboard.statusTimelineTable.title": "Durum Zaman Çizelgesi",
|
||||
"app.learningDashboard.errors.invalidToken": "Geçersiz oturum tokenı",
|
||||
"app.learningDashboard.errors.invalidToken": "Geçersiz oturum anahtarı.",
|
||||
"app.learningDashboard.errors.dataUnavailable": "Veri artık erişilebilir değil"
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
"app.chat.multi.typing": "Nhiều người dùng đang gõ",
|
||||
"app.chat.one.typing": "{0} đang gõ",
|
||||
"app.chat.two.typing": "{0} và {1} đang gõ",
|
||||
"app.chat.copySuccess": "Bản ghi cuộc trò chuyện đã sao chép",
|
||||
"app.chat.copyErr": "Sao chép bản ghi cuộc trò chuyện không thành công",
|
||||
"app.captions.label": "Chú thích",
|
||||
"app.captions.menu.close": "Đóng",
|
||||
"app.captions.menu.start": "Mở",
|
||||
@ -49,7 +51,9 @@
|
||||
"app.captions.pad.dictationStop": "Dừng đọc chính tả",
|
||||
"app.captions.pad.dictationOnDesc": "Bật nhận diện giọng nói",
|
||||
"app.captions.pad.dictationOffDesc": "Tắt nhận diện giọng nói",
|
||||
"app.captions.pad.speechRecognitionStop": "Tính năng nhận dạng giọng nói đã dừng do trình duyệt không tương thích hoặc một thời gian im lặng",
|
||||
"app.textInput.sendLabel": "Gửi",
|
||||
"app.title.defaultViewLabel": "Chế độ xem bản trình bày mặc định",
|
||||
"app.note.title": "Ghi chú chung",
|
||||
"app.note.label": "Ghi chú",
|
||||
"app.note.hideNoteLabel": "Ẩn ghi chú",
|
||||
@ -73,7 +77,10 @@
|
||||
"app.userList.moderator": "Người điều hành",
|
||||
"app.userList.mobile": "Điện thoại",
|
||||
"app.userList.guest": "Khách mời",
|
||||
"app.userList.sharingWebcam": "webcam",
|
||||
"app.userList.menuTitleContext": "Tùy chọn có sẵn",
|
||||
"app.userList.chatListItem.unreadSingular": "Một tin nhắn mới",
|
||||
"app.userList.chatListItem.unreadPlural": "{0} tin nhắn mới",
|
||||
"app.userList.menu.chat.label": "Chat riêng tư",
|
||||
"app.userList.menu.clearStatus.label": "Xóa trạng thái",
|
||||
"app.userList.menu.removeUser.label": "Loại bỏ người dùng",
|
||||
@ -129,6 +136,9 @@
|
||||
"app.media.screenshare.notSupported": "Chia sẻ màn hình không được hỗ trợ trong trình duyệt này.",
|
||||
"app.media.screenshare.autoplayBlockedDesc": "Chúng tôi cần sự cho phép của bạn để hiển thị màn hình của người thuyết trình.",
|
||||
"app.media.screenshare.autoplayAllowLabel": "Xem màn hình được chia sẻ",
|
||||
"app.screenshare.presenterLoadingLabel": "Chia sẻ màn hình của bạn đang được tải",
|
||||
"app.screenshare.viewerLoadingLabel": "Màn hình của người thuyết trình đang tải",
|
||||
"app.screenshare.presenterSharingLabel": "Bạn hiện đang chia sẻ màn hình của mình",
|
||||
"app.screenshare.screenshareFinalError": "Mã (0). Không thể chia sẻ màn hình",
|
||||
"app.screenshare.screenshareRetryError": "Mã (0). Hãy thử chia sẻ lại màn hình",
|
||||
"app.screenshare.screenshareRetryOtherEnvError": "Mã (0). Không thể chia sẻ màn hình, vui lòng thử trình duyệt hoặc thiết bị khác",
|
||||
@ -138,6 +148,8 @@
|
||||
"app.meeting.meetingTimeRemaining": "Thời gian còn lại của cuộc họp: {0}",
|
||||
"app.meeting.meetingTimeHasEnded": "Thời gian đã kết thúc. Cuộc họp sẽ sớm kết thúc",
|
||||
"app.meeting.endedByUserMessage": "Phòng họp này đã kết thúc bởi (0)",
|
||||
"app.meeting.endedByNoModeratorMessageSingular": "Cuộc họp đã kết thúc do không có người điều hành nào có mặt sau một phút",
|
||||
"app.meeting.endedByNoModeratorMessagePlural": "Cuộc họp đã kết thúc do không có người kiểm duyệt nào có mặt sau {0} phút",
|
||||
"app.meeting.endedMessage": "Bạn sẽ được chuyển tiếp trở lại màn hình chính",
|
||||
"app.meeting.alertMeetingEndsUnderMinutesSingular": "Cuộc họp sẽ đóng trong 1 phút.",
|
||||
"app.meeting.alertMeetingEndsUnderMinutesPlural": "Cuộc họp sẽ đóng {0} phút.",
|
||||
@ -174,6 +186,7 @@
|
||||
"app.presentation.presentationToolbar.fitToWidth": "Vừa với chiều rộng",
|
||||
"app.presentation.presentationToolbar.fitToPage": "Vừa với trang",
|
||||
"app.presentation.presentationToolbar.goToSlide": "Trang {0}",
|
||||
"app.presentation.placeholder": "Đang đợi bản trình bày được tải lên",
|
||||
"app.presentationUploder.title": "Bài thuyết trình",
|
||||
"app.presentationUploder.message": "Hỗ trợ các định dạng PDF, Word, Excel, Ảnh",
|
||||
"app.presentationUploder.uploadLabel": "Tải lên",
|
||||
@ -218,6 +231,7 @@
|
||||
"app.presentationUploder.completed": "{0} tải lên hoàn tất",
|
||||
"app.presentationUploder.clearErrors": "Xóa các lỗi",
|
||||
"app.presentationUploder.clearErrorsDesc": "Xóa các bài trình bày bi lỗi tải lên",
|
||||
"app.presentationUploder.uploadViewTitle": "Tải lên phần trình bày",
|
||||
"app.poll.pollPaneTitle": "Thăm dò ý kiến",
|
||||
"app.poll.quickPollTitle": "Cuộc thăm dò ý kiến nhanh",
|
||||
"app.poll.hidePollDesc": "Ẩn menu cuộc thăm dò",
|
||||
@ -233,6 +247,8 @@
|
||||
"app.poll.customPlaceholder": "Thêm tùy chọn cuộc thăm dò",
|
||||
"app.poll.noPresentationSelected": "Không có bản trình bày nào được chọn! Vui lòng chọn một.",
|
||||
"app.poll.clickHereToSelect": "Bấm vào đây để chọn",
|
||||
"app.poll.question.label" : "Nhập câu hỏi của bạn",
|
||||
"app.poll.optionalQuestion.label" : "Viết câu hỏi của bạn (tùy chọn) ...",
|
||||
"app.poll.userResponse.label" : "Phản hồi của người dùng",
|
||||
"app.poll.responseTypes.label" : "Các loại phản hồi",
|
||||
"app.poll.optionDelete.label" : "Xóa bỏ",
|
||||
@ -240,7 +256,14 @@
|
||||
"app.poll.typedResponse.desc" : "Sẽ được hiển thị với một hộp văn bản để người dùng điền vào câu trả lời của họ.",
|
||||
"app.poll.addItem.label" : "Thêm mục",
|
||||
"app.poll.start.label" : "Bắt đầu khảo sát",
|
||||
"app.poll.secretPoll.label" : "Cuộc thăm dò ý kiến ẩn danh",
|
||||
"app.poll.secretPoll.isSecretLabel": "Cuộc thăm dò là ẩn danh - bạn sẽ không thể xem các phản hồi riêng lẻ.",
|
||||
"app.poll.questionErr": "Cung cấp một câu hỏi là bắt buộc.",
|
||||
"app.poll.optionErr": "Nhập tùy chọn Khảo sát",
|
||||
"app.poll.startPollDesc": "Bắt đầu cuộc thăm dò",
|
||||
"app.poll.showRespDesc": "Hiển thị cấu hình phản hồi",
|
||||
"app.poll.addRespDesc": "Thêm đầu vào phản hồi cuộc thăm dò",
|
||||
"app.poll.deleteRespDesc": "Xóa lựa chọn {0}",
|
||||
"app.poll.t": "Đúng",
|
||||
"app.poll.f": "Sai",
|
||||
"app.poll.tf": "Đúng / Sai",
|
||||
@ -264,11 +287,16 @@
|
||||
"app.poll.answer.e": "E",
|
||||
"app.poll.liveResult.usersTitle": "Người dùng",
|
||||
"app.poll.liveResult.responsesTitle": "Phản hồi",
|
||||
"app.poll.liveResult.secretLabel": "Đây là một cuộc thăm dò ẩn danh. Các câu trả lời riêng lẻ không được hiển thị.",
|
||||
"app.poll.removePollOpt": "Đã xóa tùy chọn Cuộc thăm dò ý kiến {0}",
|
||||
"app.poll.emptyPollOpt": "Trống",
|
||||
"app.polling.pollingTitle": "Tùy chọn thăm dò",
|
||||
"app.polling.pollQuestionTitle": "Câu hỏi Khảo sát",
|
||||
"app.polling.submitLabel": "Gửi đi",
|
||||
"app.polling.submitAriaLabel": "Gửi phản hồi khảo sát",
|
||||
"app.polling.responsePlaceholder": "Nhập câu trả lời",
|
||||
"app.polling.responseSecret": "Cuộc thăm dò ẩn danh - người trình bày không thể thấy câu trả lời của bạn.",
|
||||
"app.polling.responseNotSecret": "Cuộc thăm dò bình thường - người thuyết trình có thể thấy câu trả lời của bạn.",
|
||||
"app.polling.pollAnswerLabel": "Câu trả lời {0}",
|
||||
"app.polling.pollAnswerDesc": "Chọn tùy chọn này để bỏ phiếu cho {0}",
|
||||
"app.failedMessage": "Xin lỗi, sự cố khi kết nối với máy chủ.",
|
||||
@ -325,6 +353,9 @@
|
||||
"app.actionsBar.raiseLabel": "Giơ tay",
|
||||
"app.actionsBar.label": "Thanh hành động",
|
||||
"app.actionsBar.actionsDropdown.restorePresentationLabel": "Khôi phục bản trình bày",
|
||||
"app.actionsBar.actionsDropdown.restorePresentationDesc": "Nút để khôi phục bản trình bày sau khi nó đã được thu nhỏ",
|
||||
"app.actionsBar.actionsDropdown.minimizePresentationLabel": "Thu nhỏ phần trình bày",
|
||||
"app.actionsBar.actionsDropdown.minimizePresentationDesc": "Nút thu nhỏ phần trình bày",
|
||||
"app.screenshare.screenShareLabel" : "Chia sẻ màn hình",
|
||||
"app.submenu.application.applicationSectionTitle": "Ứng dụng",
|
||||
"app.submenu.application.animationsLabel": "Đồ họa",
|
||||
@ -337,12 +368,14 @@
|
||||
"app.submenu.application.languageOptionLabel": "Chọn ngôn ngữ",
|
||||
"app.submenu.application.noLocaleOptionLabel": "Không có ngôn ngữ",
|
||||
"app.submenu.application.paginationEnabledLabel": "Phân trang video",
|
||||
"app.submenu.application.layoutOptionLabel": "Loại bố cục",
|
||||
"app.submenu.notification.SectionTitle": "Thông báo",
|
||||
"app.submenu.notification.Desc": "Xác định cách thức và những gì bạn sẽ được thông báo.",
|
||||
"app.submenu.notification.audioAlertLabel": "Cảnh báo âm thanh",
|
||||
"app.submenu.notification.pushAlertLabel": "Cảnh báo bật lên Popup",
|
||||
"app.submenu.notification.messagesLabel": "Tin nhắn trò chuyện",
|
||||
"app.submenu.notification.userJoinLabel": "Người dùng tham gia",
|
||||
"app.submenu.notification.userLeaveLabel": "Người dùng rời đi",
|
||||
"app.submenu.notification.guestWaitingLabel": "Khách đang chờ phê duyệt",
|
||||
"app.submenu.audio.micSourceLabel": "Nguồn micro",
|
||||
"app.submenu.audio.speakerSourceLabel": "nguồn loa",
|
||||
@ -451,6 +484,8 @@
|
||||
"app.audioModal.ariaTitle": "Tham gia với phương thức âm thanh",
|
||||
"app.audioModal.microphoneLabel": "Microphone",
|
||||
"app.audioModal.listenOnlyLabel": "Chỉ nghe",
|
||||
"app.audioModal.microphoneDesc": "Tham gia hội nghị âm thanh với micrô",
|
||||
"app.audioModal.listenOnlyDesc": "Tham gia hội nghị âm thanh với chế độ chỉ nghe",
|
||||
"app.audioModal.audioChoiceLabel": "Bạn muốn tham gia âm thanh như thế nào?",
|
||||
"app.audioModal.iOSBrowser": "Âm thanh / Video không được hỗ trợ",
|
||||
"app.audioModal.iOSErrorDescription": "Tại thời điểm này, âm thanh và video không được hỗ trợ trên Chrome dành cho iOS.",
|
||||
@ -476,6 +511,7 @@
|
||||
"app.audioModal.playAudio.arialabel" : "Phát âm thanh",
|
||||
"app.audioDial.tipIndicator": "Lời khuyên",
|
||||
"app.audioDial.tipMessage": "Nhấn phím '0' trên điện thoại để tắt/bật tiếng.",
|
||||
"app.audioModal.connecting": "Thiết lập kết nối âm thanh",
|
||||
"app.audioManager.joinedAudio": "Bạn đã tham gia hội nghị âm thanh",
|
||||
"app.audioManager.joinedEcho": "Bạn đã tham gia kiểm tra tiếng vang",
|
||||
"app.audioManager.leftAudio": "Bạn đã rời hội nghị âm thanh",
|
||||
@ -487,6 +523,7 @@
|
||||
"app.audioManager.mediaError": "Lỗi: Đã xảy ra sự cố khi tải các thiết bị phương tiện của bạn",
|
||||
"app.audio.joinAudio": "Tham gia âm thanh",
|
||||
"app.audio.leaveAudio": "Rời âm thanh",
|
||||
"app.audio.changeAudioDevice": "Thay đổi thiết bị âm thanh",
|
||||
"app.audio.enterSessionLabel": "Nhập phiên họp",
|
||||
"app.audio.playSoundLabel": "Phát âm thanh",
|
||||
"app.audio.backLabel": "Quay lại",
|
||||
@ -531,8 +568,11 @@
|
||||
"app.error.401": "Không được phép",
|
||||
"app.error.403": "Bạn đã bị xóa khỏi cuộc họp",
|
||||
"app.error.404": "Không tìm thấy",
|
||||
"app.error.408": "Chứng thực lỗi",
|
||||
"app.error.410": "Cuộc họp đã kết thúc",
|
||||
"app.error.500": "Rất tiếc, đã xảy ra lỗi",
|
||||
"app.error.userLoggedOut": "Người dùng có một sessionToken không hợp lệ do đăng xuất",
|
||||
"app.error.ejectedUser": "Người dùng có một sessionToken không hợp lệ do bị loại bỏ",
|
||||
"app.error.userBanned": "Người dùng đã bị cấm",
|
||||
"app.error.leaveLabel": "Đăng nhập lại",
|
||||
"app.error.fallback.presentation.title": "Đã xảy ra lỗi",
|
||||
@ -541,12 +581,16 @@
|
||||
"app.guest.waiting": "Đang chờ phê duyệt để tham gia",
|
||||
"app.guest.errorSeeConsole": "Lỗi: xem thêm ở console",
|
||||
"app.guest.noModeratorResponse": "Không có phản hồi từ Điều hành viên",
|
||||
"app.guest.noSessionToken": "Không có Mã thông báo phiên nào nhận được.",
|
||||
"app.guest.windowTitle": "Phòng chờ của khách",
|
||||
"app.guest.missingToken": "Khách bị thiếu mã thông báo phiên.",
|
||||
"app.guest.missingSession": "Khách bỏ lỡ phiên.",
|
||||
"app.guest.missingMeeting": "Phòng họp này không tồn tại",
|
||||
"app.guest.meetingEnded": "Cuộc họp kết thúc.",
|
||||
"app.guest.guestWait": "Vui lòng đợi Người điều hành cho phép bạn vào phòng họp",
|
||||
"app.guest.guestDeny": "Khách bị từ chối tham gia cuộc họp.",
|
||||
"app.guest.seatWait": "Khách chờ lấy chỗ trong cuộc họp.",
|
||||
"app.guest.allow": "Khách đã chấp thuận và chuyển hướng đến cuộc họp.",
|
||||
"app.userList.guest.waitingUsers": "Người dùng đang chờ",
|
||||
"app.userList.guest.waitingUsersTitle": "Quản lý người dùng",
|
||||
"app.userList.guest.optionTitle": "Đánh giá người dùng đang chờ xử lý",
|
||||
@ -559,6 +603,7 @@
|
||||
"app.userList.guest.pendingGuestAlert": "Đã tham gia phiên và đang chờ sự chấp thuận của bạn.",
|
||||
"app.userList.guest.rememberChoice": "Ghi nhớ lựa chọn",
|
||||
"app.userList.guest.emptyMessage": "Hiện tại không có tin nhắn",
|
||||
"app.userList.guest.inputPlaceholder": "Thông báo đến phòng chờ của khách",
|
||||
"app.userList.guest.acceptLabel": "Chấp nhận",
|
||||
"app.userList.guest.denyLabel": "Từ chối",
|
||||
"app.user-info.title": "Tra cứu thư mục",
|
||||
@ -577,6 +622,7 @@
|
||||
"app.notification.recordingPaused": "Phiên này đã dừng ghi hình",
|
||||
"app.notification.recordingAriaLabel": "Thời gian ghi hình ",
|
||||
"app.notification.userJoinPushAlert": "{0} đã tham gia vào phiên",
|
||||
"app.notification.userLeavePushAlert": "{0} đã rời khỏi phiên họp",
|
||||
"app.submenu.notification.raiseHandLabel": "Giơ tay",
|
||||
"app.shortcut-help.title": "Các phím tắt bàn phím",
|
||||
"app.shortcut-help.accessKeyNotAvailable": "Các phím truy cập không khả dụng",
|
||||
@ -592,6 +638,7 @@
|
||||
"app.shortcut-help.closePrivateChat": "Đóng cuộc trò chuyện riêng tư",
|
||||
"app.shortcut-help.openActions": "Mở menu tác vụ",
|
||||
"app.shortcut-help.raiseHand": "Chuyển đổi giơ tay",
|
||||
"app.shortcut-help.openDebugWindow": "Mở cửa sổ debug",
|
||||
"app.shortcut-help.openStatus": "Mở menu trạng thái",
|
||||
"app.shortcut-help.togglePan": "Kích hoạt công cụ Pan (Người trình bày)",
|
||||
"app.shortcut-help.toggleFullscreen": "Chuyển đổi Toàn màn hình (Người trình bày)",
|
||||
@ -619,14 +666,25 @@
|
||||
"app.guest-policy.button.askModerator": "Hỏi người kiểm duyệt",
|
||||
"app.guest-policy.button.alwaysAccept": "Luôn chấp nhận",
|
||||
"app.guest-policy.button.alwaysDeny": "Luôn từ chối",
|
||||
"app.guest-policy.policyBtnDesc": "Đặt chính sách phòng họp cho khách",
|
||||
"app.connection-status.ariaTitle": "Phương thức trạng thái kết nối",
|
||||
"app.connection-status.title": "Tình trạng kết nối",
|
||||
"app.connection-status.description": "Xem trạng thái kết nối của người dùng",
|
||||
"app.connection-status.empty": "Hiện không có vấn đề kết nối nào được báo cáo",
|
||||
"app.connection-status.more": "thêm",
|
||||
"app.connection-status.copy": "Sao chép dữ liệu mạng",
|
||||
"app.connection-status.copied": "Đã sao chép",
|
||||
"app.connection-status.jitter": "Nhiễu",
|
||||
"app.connection-status.label": "Tình trạng kết nối",
|
||||
"app.connection-status.no": "Không",
|
||||
"app.connection-status.notification": "Mất kết nối của bạn đã được phát hiện",
|
||||
"app.connection-status.offline": "ngoại tuyến",
|
||||
"app.connection-status.lostPackets": "Mất gói",
|
||||
"app.connection-status.usingTurn": "Sử dụng TURN",
|
||||
"app.connection-status.yes": "Có",
|
||||
"app.learning-dashboard.label": "Bảng điểu khiển phiên học",
|
||||
"app.learning-dashboard.description": "Mở bảng điều khiển với các hoạt động của người dùng",
|
||||
"app.learning-dashboard.clickHereToOpen": "Mở bảng điều khiển phiên học",
|
||||
"app.recording.startTitle": "Bắt đầu ghi hình",
|
||||
"app.recording.stopTitle": "Dừng ghi hình",
|
||||
"app.recording.resumeTitle": "Tiếp tục ghi hình",
|
||||
@ -648,6 +706,8 @@
|
||||
"app.videoPreview.webcamOptionLabel": "Chọn webcam",
|
||||
"app.videoPreview.webcamPreviewLabel": "Xem trước webcam",
|
||||
"app.videoPreview.webcamSettingsTitle": "Cài đặt webcam",
|
||||
"app.videoPreview.webcamVirtualBackgroundLabel": "Cài đặt nền ảo",
|
||||
"app.videoPreview.webcamVirtualBackgroundDisabledLabel": "Thiết bị này không hỗ trợ nền ảo",
|
||||
"app.videoPreview.webcamNotFoundLabel": "Không tìm thấy webcam",
|
||||
"app.videoPreview.profileNotFoundLabel": "Không có cấu hình máy ảnh được hỗ trợ",
|
||||
"app.video.joinVideo": "Chia sẻ webcam",
|
||||
@ -657,10 +717,17 @@
|
||||
"app.video.iceConnectionStateError": "Lỗi kết nối (ICE error 1107)",
|
||||
"app.video.permissionError": "Lỗi chia sẻ webcam. Xin cho quyền sử dụng",
|
||||
"app.video.sharingError": "Lỗi chia sẻ webcam",
|
||||
"app.video.abortError": "Đã xảy ra sự cố không xác định khiến máy ảnh của bạn không được sử dụng",
|
||||
"app.video.overconstrainedError": "Máy ảnh của bạn không hỗ trợ cấu hình chất lượng này",
|
||||
"app.video.securityError": "Trình duyệt của bạn đã vô hiệu hóa việc sử dụng máy ảnh. Thử một trình duyệt khác",
|
||||
"app.video.typeError": "Cấu hình chất lượng máy ảnh không hợp lệ. Liên hệ với quản trị viên của bạn",
|
||||
"app.video.notFoundError": "Không thể tìm thấy webcam. Hãy đảm bảo rằng nó được kết nối",
|
||||
"app.video.notAllowed": "Thiếu quyền chia sẻ webcam, vui lòng đảm bảo quyền trình duyệt của bạn",
|
||||
"app.video.notSupportedError": "Chỉ có thể chia sẻ video webcam với các nguồn an toàn, hãy đảm bảo chứng chỉ SSL của bạn hợp lệ",
|
||||
"app.video.notReadableError": "Không thể tải video webcam. Hãy đảm bảo rằng một chương trình khác không sử dụng webcam ",
|
||||
"app.video.timeoutError": "Trình duyệt không phản hồi kịp.",
|
||||
"app.video.genericError": "Đã xảy ra lỗi không xác định với thiết bị ({0})",
|
||||
"app.video.mediaTimedOutError": "Luồng webcam của bạn đã bị gián đoạn. Hãy thử chia sẻ lại",
|
||||
"app.video.mediaFlowTimeout1020": "Phương tiện không thể kết nối với máy chủ (lỗi 1020)",
|
||||
"app.video.suggestWebcamLock": "Thực hiện cài đặt khóa webcam người xem?",
|
||||
"app.video.suggestWebcamLockReason": "(điều này sẽ cải thiện sự ổn định của cuộc họp)",
|
||||
@ -675,7 +742,16 @@
|
||||
"app.video.videoMenuDesc": "Mở menu video",
|
||||
"app.video.pagination.prevPage": "Xem các video trước",
|
||||
"app.video.pagination.nextPage": "Xem các video tiếp theo",
|
||||
"app.video.clientDisconnected": "Không thể chia sẻ webcam do sự cố kết nối",
|
||||
"app.video.virtualBackground.none": "Không có",
|
||||
"app.video.virtualBackground.blur": "Làm mờ",
|
||||
"app.video.virtualBackground.genericError": "Không áp dụng được hiệu ứng máy ảnh. Thử lại.",
|
||||
"app.video.virtualBackground.camBgAriaDesc": "Đặt nền ảo của webcam thành {0}",
|
||||
"app.video.dropZoneLabel": "Thả ở đây",
|
||||
"app.fullscreenButton.label": "Làm {0} toàn màn hình",
|
||||
"app.fullscreenUndoButton.label": "Hoàn tác {0} toàn màn hình",
|
||||
"app.switchButton.expandLabel": "Mở rộng video chia sẻ màn hình",
|
||||
"app.switchButton.shrinkLabel": "Thu nhỏ video chia sẻ màn hình",
|
||||
"app.sfu.mediaServerConnectionError2000": "Không thể kết nối với máy chủ (lỗi 2000)",
|
||||
"app.sfu.mediaServerOffline2001": "Máy chủ phương tiện đang ngoại tuyến. Vui lòng thử lại sau (lỗi 2001)",
|
||||
"app.sfu.mediaServerNoResources2002": "Máy chủ phương tiện không có sẵn nguồn (error 2002)",
|
||||
@ -716,12 +792,17 @@
|
||||
"app.whiteboard.toolbar.clear": "Xóa hoàn tác chú thích",
|
||||
"app.whiteboard.toolbar.multiUserOn": "Bật bảng trắng nhiều người dùng",
|
||||
"app.whiteboard.toolbar.multiUserOff": "Tắt bảng trắng nhiều người dùng",
|
||||
"app.whiteboard.toolbar.palmRejectionOn": "Bật tính năng từ chối bằng lòng bàn tay",
|
||||
"app.whiteboard.toolbar.palmRejectionOff": "Tắt tính năng từ chối lòng bàn tay",
|
||||
"app.whiteboard.toolbar.fontSize": "Danh sách kích thước phông chữ",
|
||||
"app.whiteboard.toolbarAriaLabel": "Các công cụ thuyết trình",
|
||||
"app.feedback.title": "Bạn đã đăng xuất khỏi cuộc họp",
|
||||
"app.feedback.subtitle": "Chúng tôi rất muốn nghe về trải nghiệm của bạn với hệ thống này (tùy chọn)",
|
||||
"app.feedback.textarea": "Làm thế nào chúng tôi có thể cải thiện TUV NORD MEET?",
|
||||
"app.feedback.sendFeedback": "Gửi thông tin phản hồi",
|
||||
"app.feedback.sendFeedbackDesc": "Gửi phản hồi và rời khỏi cuộc họp",
|
||||
"app.videoDock.webcamMirrorLabel": "Phản chiếu",
|
||||
"app.videoDock.webcamMirrorDesc": "Phản chiếu webcam đã chọn",
|
||||
"app.videoDock.webcamFocusLabel": "Tập trung",
|
||||
"app.videoDock.webcamFocusDesc": "Tập trung vào webcam đã chọn",
|
||||
"app.videoDock.webcamUnfocusLabel": "Bỏ tập trung",
|
||||
|
@ -1,6 +1,5 @@
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { checkElement } = require('../core/util');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
|
||||
class Create {
|
||||
@ -62,7 +61,7 @@ class Create {
|
||||
// Check if Breakoutrooms have been created
|
||||
async testCreatedBreakout(testName) {
|
||||
try {
|
||||
const resp = await this.modPage1.page.evaluate(checkElement, e.breakoutRoomsItem);
|
||||
const resp = await this.modPage1.hasElement(e.breakoutRoomsItem);
|
||||
if (resp === true) {
|
||||
await this.modPage1.screenshot(`${testName}`, `05-page01-success-${testName}`);
|
||||
|
||||
@ -88,8 +87,7 @@ class Create {
|
||||
await this.modPage2.waitAndClick(e.chatButton);
|
||||
await this.modPage2.waitAndClick(e.breakoutRoomsItem);
|
||||
|
||||
await this.modPage2.waitAndClick(e.generateRoom1);
|
||||
await this.modPage2.waitAndClick(e.joinGeneratedRoom1);
|
||||
await this.modPage2.waitAndClick(e.askJoinRoom1);
|
||||
await this.modPage2.waitForSelector(e.alreadyConnected, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
const breakoutModPage2 = await this.modPage2.getLastTargetPage();
|
||||
@ -107,8 +105,7 @@ class Create {
|
||||
} else if (testName === 'joinBreakoutroomsWithVideo') {
|
||||
await this.modPage2.init(true, true, testName, 'Moderator2', this.modPage1.meetingId);
|
||||
await this.modPage2.waitAndClick(e.breakoutRoomsButton);
|
||||
await this.modPage2.waitAndClick(e.generateRoom1);
|
||||
await this.modPage2.waitAndClick(e.joinGeneratedRoom1);
|
||||
await this.modPage2.waitAndClick(e.askJoinRoom1);
|
||||
await this.modPage2.waitForSelector(e.alreadyConnected);
|
||||
|
||||
const breakoutModPage2 = await this.modPage2.getLastTargetPage();
|
||||
@ -116,18 +113,15 @@ class Create {
|
||||
|
||||
await breakoutModPage2.bringToFront();
|
||||
await breakoutModPage2.closeAudioModal();
|
||||
await breakoutModPage2.waitAndClick(e.joinVideo);
|
||||
const parsedSettings = await this.modPage2.getSettingsYaml();
|
||||
const videoPreviewTimeout = parseInt(parsedSettings.public.kurento.gUMTimeout);
|
||||
await breakoutModPage2.waitAndClick(e.videoPreview, videoPreviewTimeout);
|
||||
await breakoutModPage2.waitAndClick(e.startSharingWebcam);
|
||||
await breakoutModPage2.shareWebcam(true, videoPreviewTimeout);
|
||||
|
||||
await breakoutModPage2.screenshot(testName, '00-breakout-page03-user-joined-with-webcam-before-check');
|
||||
} else if (testName === 'joinBreakoutroomsAndShareScreen') {
|
||||
await this.modPage2.init(true, true, testName, 'Moderator2', this.modPage1.meetingId);
|
||||
await this.modPage2.waitAndClick(e.breakoutRoomsButton);
|
||||
await this.modPage2.waitAndClick(e.generateRoom1);
|
||||
await this.modPage2.waitAndClick(e.joinGeneratedRoom1);
|
||||
await this.modPage2.waitAndClick(e.askJoinRoom1);
|
||||
await this.modPage2.waitForSelector(e.alreadyConnected);
|
||||
const breakoutModPage2 = await this.modPage2.getLastTargetPage();
|
||||
|
||||
|
@ -49,8 +49,7 @@ exports.alreadyConnected = 'span[class^="alreadyConnected--"]';
|
||||
exports.breakoutJoin = '[data-test="breakoutJoin"]';
|
||||
exports.userJoined = 'div[aria-label^="Moderator3"]';
|
||||
exports.breakoutRoomsButton = 'div[aria-label="Breakout Rooms"]';
|
||||
exports.generateRoom1 = 'button[aria-label="Generate URL Room 1"]';
|
||||
exports.joinGeneratedRoom1 = 'button[aria-label="Generated Room 1"]';
|
||||
exports.askJoinRoom1 = 'button[aria-label="Ask to join Room 1"]';
|
||||
exports.joinRoom1 = 'button[aria-label="Join room Room 1"]';
|
||||
exports.allowChoiceRoom = 'input[id="freeJoinCheckbox"]';
|
||||
exports.labelGeneratingURL = 'span[data-test="labelGeneratingURL"]';
|
||||
@ -207,6 +206,8 @@ exports.chatPanel = 'section[data-test="chatPanel"]';
|
||||
exports.userListPanel = 'div[data-test="userListPanel"]';
|
||||
exports.multiWhiteboardTool = 'span[data-test="multiWhiteboardTool"]'
|
||||
exports.connectionStatusBtn = 'button[data-test="connectionStatusButton"]';
|
||||
exports.connectionDataContainer = '[class^=networkDataContainer--]';
|
||||
exports.connectionNetwordData = '[class^=networkData--]';
|
||||
|
||||
// Webcam
|
||||
exports.joinVideo = 'button[data-test="joinVideo"]';
|
||||
|
@ -8,7 +8,7 @@ const path = require('path');
|
||||
const PuppeteerVideoRecorder = require('puppeteer-video-recorder');
|
||||
const helper = require('./helper');
|
||||
const params = require('./params');
|
||||
const { ELEMENT_WAIT_TIME } = require('./constants');
|
||||
const { ELEMENT_WAIT_TIME, VIDEO_LOADING_WAIT_TIME } = require('./constants');
|
||||
const { getElementLength } = require('./util');
|
||||
const e = require('./elements');
|
||||
const { NETWORK_PRESETS } = require('./profiles');
|
||||
@ -104,6 +104,17 @@ class Page {
|
||||
await this.waitForSelector(e.isTalking);
|
||||
}
|
||||
|
||||
async shareWebcam(shouldConfirmSharing, videoPreviewTimeout = ELEMENT_WAIT_TIME) {
|
||||
await this.waitAndClick(e.joinVideo);
|
||||
if (shouldConfirmSharing) {
|
||||
await this.waitForSelector(e.videoPreview, videoPreviewTimeout);
|
||||
await this.waitAndClick(e.startSharingWebcam);
|
||||
}
|
||||
await this.waitForSelector(e.webcamConnecting);
|
||||
await this.waitForSelector(e.webcamVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
await this.waitForSelector(e.leaveVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
}
|
||||
|
||||
// Joining audio with microphone
|
||||
async joinMicrophoneWithoutEchoTest() {
|
||||
await this.waitAndClick(e.joinAudio);
|
||||
@ -214,16 +225,6 @@ class Page {
|
||||
}
|
||||
}
|
||||
|
||||
async isNotVisible(element, timeout = ELEMENT_WAIT_TIME) {
|
||||
try {
|
||||
await this.hasElement(element, false, timeout);
|
||||
return true;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// async emulateMobile(userAgent) {
|
||||
// await this.page.setUserAgent(userAgent);
|
||||
// }
|
||||
@ -243,7 +244,7 @@ class Page {
|
||||
}
|
||||
}
|
||||
|
||||
async hasElement(element, visible = false, timeout = ELEMENT_WAIT_TIME) {
|
||||
async hasElement(element, visible = true, timeout = ELEMENT_WAIT_TIME) {
|
||||
try {
|
||||
await this.page.waitForSelector(element, { visible, timeout });
|
||||
return true;
|
||||
|
@ -3,13 +3,11 @@ exports.listenOnlyMode = 'userdata-bbb_listen_only_mode=false';
|
||||
exports.forceListenOnly = 'userdata-bbb_force_listen_only=true';
|
||||
exports.skipCheck = 'userdata-bbb_skip_check_audio=true';
|
||||
exports.skipCheckOnFirstJoin = 'userdata-bbb_skip_check_audio_on_first_join=true';
|
||||
const docTitle = 'puppeteer';
|
||||
exports.docTitle = docTitle;
|
||||
exports.clientTitle = `userdata-bbb_client_title=${docTitle}`;
|
||||
exports.docTitle = 'puppeteer';
|
||||
exports.clientTitle = `userdata-bbb_client_title=${this.docTitle}`;
|
||||
exports.askForFeedbackOnLogout = 'userdata-bbb_ask_for_feedback_on_logout=true';
|
||||
exports.displayBrandingArea = 'userdata-bbb_display_branding_area=true';
|
||||
exports.logo = 'logo=https://bigbluebutton.org/wp-content/themes/bigbluebutton/library/images/bigbluebutton-logo.png';
|
||||
exports.shortcuts = 'userdata-bbb_shortcuts=["openOptions", "toggleUserList", "toggleMute", "joinAudio", "leaveAudio", "togglePublicChat", "hidePrivateChat", "closePrivateChat", "openActions", "openStatus"]';
|
||||
exports.enableScreensharing = 'userdata-bbb_enable_screen_sharing=false';
|
||||
exports.enableVideo = 'userdata-bbb_enable_video=false';
|
||||
exports.autoShareWebcam = 'userdata-bbb_auto_share_webcam=true';
|
||||
@ -33,3 +31,35 @@ exports.skipVideoPreview = 'userdata-bbb_skip_video_preview=true';
|
||||
exports.skipVideoPreviewOnFirstJoin = 'userdata-bbb_skip_video_preview_on_first_join=true';
|
||||
exports.mirrorOwnWebcam = 'userdata-bbb_mirror_own_webcam=true';
|
||||
exports.showParticipantsOnLogin = 'userdata-bbb_show_participants_on_login=false';
|
||||
|
||||
// Shortcuts
|
||||
exports.shortcuts = 'userdata-bbb_shortcuts=[$]';
|
||||
exports.initialShortcuts = [{
|
||||
param: 'openOptions',
|
||||
key: 'O'
|
||||
}, {
|
||||
param: 'toggleUserList',
|
||||
key: 'U'
|
||||
}, {
|
||||
param: 'togglePublicChat',
|
||||
key: 'P'
|
||||
}, {
|
||||
param: 'openActions',
|
||||
key: 'A'
|
||||
}, {
|
||||
param: 'joinAudio',
|
||||
key: 'J'
|
||||
}];
|
||||
exports.laterShortcuts = [{
|
||||
param: 'toggleMute',
|
||||
key: 'M'
|
||||
}, {
|
||||
param: 'leaveAudio',
|
||||
key: 'L'
|
||||
}, {
|
||||
param: 'hidePrivateChat',
|
||||
key: 'H'
|
||||
}, {
|
||||
param: 'closePrivateChat',
|
||||
key: 'G'
|
||||
}];
|
||||
|
@ -3,7 +3,7 @@ const e = require('../core/elements');
|
||||
const c = require('./constants');
|
||||
const util = require('./util');
|
||||
const { VIDEO_LOADING_WAIT_TIME, ELEMENT_WAIT_LONGER_TIME } = require('../core/constants'); // core constants (Timeouts vars imported)
|
||||
const { checkElementLengthEqualTo, checkElementLengthDifferentTo } = require('../core/util');
|
||||
const { checkElementLengthEqualTo, checkElement } = require('../core/util');
|
||||
|
||||
class CustomParameters {
|
||||
constructor() {
|
||||
@ -25,7 +25,7 @@ class CustomParameters {
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.waitForSelector(e.chatMessages);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthEqualTo, e.audioModal, 0);
|
||||
const resp = await this.page1.wasRemoved(e.audioModal);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -96,7 +96,7 @@ class CustomParameters {
|
||||
await this.page1.screenshot(`${testName}`, `02-${testName}`);
|
||||
await this.page1.waitForElementHandleToBeRemoved(e.connectingStatus, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.page1.screenshot(`${testName}`, `03-${testName}`);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthEqualTo, e.echoYesButton, 0);
|
||||
const resp = await this.page1.wasRemoved(e.echoYesButton);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `04-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -118,13 +118,13 @@ class CustomParameters {
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.waitAndClick(e.microphoneButton);
|
||||
const firstCheck = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.connecting, 0);
|
||||
const firstCheck = await this.page1.hasElement(e.connecting);
|
||||
await this.page1.screenshot(`${testName}`, `02-${testName}`);
|
||||
await this.page1.leaveAudio();
|
||||
await this.page1.screenshot(`${testName}`, `03-${testName}`);
|
||||
await this.page1.waitAndClick(e.joinAudio);
|
||||
await this.page1.waitAndClick(e.microphoneButton);
|
||||
const secondCheck = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.connectingToEchoTest, 0);
|
||||
const secondCheck = await this.page1.hasElement(e.connectingToEchoTest);
|
||||
|
||||
if (firstCheck !== secondCheck) {
|
||||
await this.page1.screenshot(`${testName}`, `04-fail-${testName}`);
|
||||
@ -175,7 +175,7 @@ class CustomParameters {
|
||||
await this.page1.waitForSelector(e.meetingEndedModal);
|
||||
await this.page1.screenshot(`${testName}`, `04-${testName}`);
|
||||
await this.page1.logger('audio modal closed');
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.rating, 0);
|
||||
const resp = await this.page1.hasElement(e.rating);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `05-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -199,7 +199,7 @@ class CustomParameters {
|
||||
await this.page1.screenshot(`${testName}`, `02-${testName}`);
|
||||
await this.page1.logger('audio modal closed');
|
||||
await this.page1.waitForSelector(e.userListContent);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.brandingAreaLogo, 0);
|
||||
const resp = await this.page1.hasElement(e.brandingAreaLogo);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `03-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -218,23 +218,30 @@ class CustomParameters {
|
||||
async shortcuts(testName, customParameter) {
|
||||
try {
|
||||
await this.page1.init(true, true, testName, 'Moderator', undefined, customParameter);
|
||||
await this.page2.init(false, true, testName, 'Attendee', this.page1.meetingId);
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.screenshot(`${testName}`, `02-${testName}`);
|
||||
await this.page1.logger('audio modal closed');
|
||||
await this.page1.waitForSelector(e.options);
|
||||
await this.page1.page.keyboard.down('Alt');
|
||||
await this.page1.page.keyboard.press('O');
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthEqualTo, e.verticalListOptions, 0);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `03-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
return false;
|
||||
}
|
||||
await this.page1.screenshot(`${testName}`, `03-success-${testName}`);
|
||||
await this.page1.logger(testName, ' passed');
|
||||
await this.page1.screenshot(`${testName}`, '01-after-close-audio-modal');
|
||||
|
||||
return resp === true;
|
||||
// Check the initial shortcuts that can be used right after joining the meeting
|
||||
const check1 = await util.checkShortcutsArray(this.page1, c.initialShortcuts);
|
||||
if (!check1) return false;
|
||||
await this.page1.bringToFront();
|
||||
|
||||
// Join audio
|
||||
await this.page1.waitAndClick(e.joinAudio);
|
||||
await this.page1.joinMicrophone();
|
||||
await this.page1.screenshot(`${testName}`, '02-after-join-audio');
|
||||
|
||||
// Open private chat
|
||||
await this.page1.waitAndClick(e.userListItem);
|
||||
await this.page1.waitAndClick(e.activeChat);
|
||||
await this.page1.waitForSelector(e.hidePrivateChat);
|
||||
await this.page1.screenshot(`${testName}`, '03-after-open-private-chat');
|
||||
|
||||
// Check the later shortcuts that can be used after joining audio and opening private chat
|
||||
const check2 = await util.checkShortcutsArray(this.page1, c.laterShortcuts);
|
||||
|
||||
return check2 === true;
|
||||
} catch (err) {
|
||||
await this.page1.logger(err);
|
||||
return false;
|
||||
@ -246,7 +253,7 @@ class CustomParameters {
|
||||
await this.page1.init(true, true, testName, 'Moderator', undefined, customParameter);
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthEqualTo, e.startScreenSharing, 0);
|
||||
const resp = await this.page1.wasRemoved(e.startScreenSharing);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -267,7 +274,7 @@ class CustomParameters {
|
||||
await this.page1.init(true, true, testName, 'Moderator', undefined, customParameter);
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthEqualTo, e.joinVideo, 0);
|
||||
const resp = await this.page1.wasRemoved(e.joinVideo);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -450,7 +457,10 @@ class CustomParameters {
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.waitForSelector(e.actions);
|
||||
await this.page1.screenshot(`${testName}`, `02-${testName}`);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.defaultContent, 0);
|
||||
const checkPresentationButton = await this.page1.page.evaluate(checkElement, e.restorePresentation);
|
||||
const checkPresentationPlaceholder = await this.page1.page.evaluate(checkElement, e.presentationPlaceholder);
|
||||
const resp = !(checkPresentationButton || checkPresentationPlaceholder);
|
||||
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `03-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -473,7 +483,7 @@ class CustomParameters {
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.waitForSelector(e.actions);
|
||||
await this.page1.screenshot(`${testName}`, `02-${testName}`);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.notificationBar, 0);
|
||||
const resp = await this.page1.hasElement(e.notificationBar);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `03-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -518,7 +528,7 @@ class CustomParameters {
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.waitForSelector(e.actions);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.restorePresentation, 0) && await this.page1.page.evaluate(checkElementLengthDifferentTo, e.defaultContent, 0);
|
||||
const resp = await this.page1.hasElement(e.restorePresentation) && await this.page1.hasElement(e.defaultContent);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -585,14 +595,13 @@ class CustomParameters {
|
||||
await this.page1.screenshot(`${testName}`, `05-page1-${testName}`);
|
||||
await this.page2.screenshot(`${testName}`, `06-page2-${testName}`);
|
||||
|
||||
const test = await this.page2.page.evaluate(checkElementLengthDifferentTo, e.restorePresentation, 0);
|
||||
const test = await this.page2.page.evaluate(checkElement, e.restorePresentation);
|
||||
const resp = (zoomInCase && zoomOutCase && pollCase && previousSlideCase && nextSlideCase && annotationCase && test);
|
||||
if (resp) {
|
||||
await this.page2.screenshot(`${testName}`, `07-page2-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
return false;
|
||||
}
|
||||
await this.page2.page.evaluate(checkElementLengthEqualTo, e.restorePresentation, 0);
|
||||
await this.page2.screenshot(`${testName}`, `07-page2-success-${testName}`);
|
||||
await this.page1.logger(testName, ' passed');
|
||||
|
||||
@ -617,7 +626,7 @@ class CustomParameters {
|
||||
await this.page1.screenshot(`${testName}`, `02-page1-${testName}`);
|
||||
await this.page2.screenshot(`${testName}`, `03-page2-${testName}`);
|
||||
|
||||
const test = await this.page2.page.evaluate(checkElementLengthDifferentTo, e.restorePresentation, 0);
|
||||
const test = await this.page2.page.evaluate(checkElement, e.restorePresentation);
|
||||
if (pollCase && test) {
|
||||
await this.page2.screenshot(`${testName}`, `04-page2-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
@ -681,31 +690,22 @@ class CustomParameters {
|
||||
await this.page1.init(true, true, testName, 'Moderator1', undefined, customParameter);
|
||||
await this.page1.startRecording(testName);
|
||||
await this.page1.screenshot(`${testName}`, `01-${testName}`);
|
||||
await this.page1.waitAndClick(e.joinVideo);
|
||||
const firstCheck = await this.page1.page.evaluate(checkElementLengthEqualTo, e.webcamSettingsModal, 0);
|
||||
await this.page1.shareWebcam(false);
|
||||
|
||||
await this.page1.waitAndClick(e.leaveVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
await this.page1.waitForElementHandleToBeRemoved(e.webcamVideo, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.page1.waitForElementHandleToBeRemoved(e.leaveVideo, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
await this.page1.waitAndClick(e.joinVideo);
|
||||
const parsedSettings = await this.page1.getSettingsYaml();
|
||||
const videoPreviewTimeout = parseInt(parsedSettings.public.kurento.gUMTimeout);
|
||||
await this.page1.waitForSelector(e.videoPreview, videoPreviewTimeout);
|
||||
await this.page1.waitForSelector(e.startSharingWebcam);
|
||||
const secondCheck = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.webcamSettingsModal, 0);
|
||||
await this.page1.waitAndClick(e.startSharingWebcam);
|
||||
await this.page1.waitForSelector(e.webcamConnecting);
|
||||
await this.page1.shareWebcam(true, videoPreviewTimeout);
|
||||
|
||||
if (firstCheck !== secondCheck) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
return false;
|
||||
}
|
||||
await this.page1.screenshot(`${testName}`, `02-success-${testName}`);
|
||||
await this.page1.logger(testName, ' passed');
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(err);
|
||||
return false;
|
||||
}
|
||||
@ -719,7 +719,7 @@ class CustomParameters {
|
||||
await this.page1.waitAndClick(e.joinVideo);
|
||||
await this.page1.waitForSelector(e.webcamMirroredVideoPreview);
|
||||
await this.page1.waitAndClick(e.startSharingWebcam);
|
||||
const resp = await this.page1.page.evaluate(checkElementLengthDifferentTo, e.webcamMirroredVideoContainer, 0);
|
||||
const resp = await this.page1.hasElement(e.webcamMirroredVideoContainer);
|
||||
if (!resp) {
|
||||
await this.page1.screenshot(`${testName}`, `02-fail-${testName}`);
|
||||
await this.page1.logger(testName, ' failed');
|
||||
|
@ -207,14 +207,15 @@ const customParametersTest = () => {
|
||||
try {
|
||||
const testName = 'shortcuts';
|
||||
await page.logger('before ', testName);
|
||||
response = await test.shortcuts(testName, util.encodeCustomParams(c.shortcuts));
|
||||
const shortcutParam = util.getAllShortcutParams();
|
||||
response = await test.shortcuts(testName, util.encodeCustomParams(shortcutParam));
|
||||
await test.page1.stopRecording();
|
||||
screenshot = await test.page1.page.screenshot();
|
||||
await page.logger('after ', testName);
|
||||
} catch (err) {
|
||||
await page.logger(err);
|
||||
} finally {
|
||||
await test.closePage(test.page1);
|
||||
await test.close(test.page1, test.page2);
|
||||
}
|
||||
expect(response).toBe(true);
|
||||
Page.checkRegression(0.5, screenshot);
|
||||
|
@ -1,7 +1,8 @@
|
||||
const path = require('path');
|
||||
const e = require('../core/elements');
|
||||
const c = require('./constants');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { checkElementLengthEqualTo, checkElementLengthDifferentTo, checkElementText } = require('../core/util');
|
||||
const { checkElementLengthEqualTo, checkElementLengthDifferentTo, checkElementText, checkElement } = require('../core/util');
|
||||
|
||||
async function autoJoinTest(test) {
|
||||
try {
|
||||
@ -160,6 +161,28 @@ function encodeCustomParams(param) {
|
||||
}
|
||||
}
|
||||
|
||||
function getAllShortcutParams() {
|
||||
const getParams = (shortcutArray) => {
|
||||
return Object.values(shortcutArray.map(e => `"${e.param}"`));
|
||||
}
|
||||
return c.shortcuts.replace('$', [...getParams(c.initialShortcuts), ...getParams(c.laterShortcuts)]);
|
||||
}
|
||||
|
||||
async function checkAccesskey(test, key) {
|
||||
return test.page.evaluate(checkElement, `[accesskey="${key}"]`);
|
||||
}
|
||||
|
||||
async function checkShortcutsArray(test, shortcut) {
|
||||
for (const { param, key } of shortcut) {
|
||||
const resp = await checkAccesskey(test, key);
|
||||
if (!resp) {
|
||||
await test.logger(`${param} shortcut failed`)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
exports.zoomIn = zoomIn;
|
||||
exports.zoomOut = zoomOut;
|
||||
exports.poll = poll;
|
||||
@ -173,3 +196,6 @@ exports.listenOnlyMode = listenOnlyMode;
|
||||
exports.forceListenOnly = forceListenOnly;
|
||||
exports.skipCheck = skipCheck;
|
||||
exports.encodeCustomParams = encodeCustomParams;
|
||||
exports.getAllShortcutParams = getAllShortcutParams;
|
||||
exports.checkAccesskey = checkAccesskey;
|
||||
exports.checkShortcutsArray = checkShortcutsArray;
|
||||
|
@ -116,7 +116,7 @@ class Presentation {
|
||||
await this.userPage.screenshot(testName, `3-userPage-after-allow-download-and-save-[${this.modPage.meetingId}]`);
|
||||
await this.userPage.waitForSelector(e.toastDownload);
|
||||
// check download button in presentation after ALLOW it - should be true
|
||||
const hasPresentationDownloadBtnAfterAllow = await this.userPage.page.evaluate(checkElement, e.presentationDownloadBtn);
|
||||
const hasPresentationDownloadBtnAfterAllow = await this.userPage.hasElement(e.presentationDownloadBtn);
|
||||
|
||||
// disallow the presentation download
|
||||
await this.modPage.waitAndClick(e.actions);
|
||||
|
@ -2,7 +2,6 @@ const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const c = require('../core/constants');
|
||||
const util = require('./util');
|
||||
const { checkElementLengthEqualTo } = require('../core/util');
|
||||
|
||||
class Stress {
|
||||
constructor() {
|
||||
@ -19,7 +18,7 @@ class Stress {
|
||||
await this.modPage.waitForSelector(e.userAvatar);
|
||||
const hasPresenterClass = await this.modPage.page.evaluate(util.checkIncludeClass, e.userAvatar, e.presenterClassName);
|
||||
await this.modPage.waitAndClick(e.actions);
|
||||
const canStartPoll = await this.modPage.page.evaluate(checkElementLengthEqualTo, e.polling, 1);
|
||||
const canStartPoll = await this.modPage.hasElement(e.polling);
|
||||
if (!hasPresenterClass || !canStartPoll) {
|
||||
failureCount++;
|
||||
await this.modPage.screenshot(testName, `loop-${i}-failure-${testName}`);
|
||||
|
@ -3,7 +3,6 @@ const { exec } = require("child_process");
|
||||
const { CLIENT_RECONNECTION_TIMEOUT } = require('../core/constants'); // core constants (Timeouts vars imported)
|
||||
const { sleep } = require('../core/helper');
|
||||
const e = require('../core/elements');
|
||||
const { checkElementLengthDifferentTo } = require('../core/util');
|
||||
|
||||
class Trigger extends Page {
|
||||
constructor() {
|
||||
@ -30,7 +29,7 @@ class Trigger extends Page {
|
||||
await sleep(3000);
|
||||
await this.screenshot(`${testName}`, `03-after-meteor-reconnection-[${this.meetingId}]`);
|
||||
|
||||
const findUnauthorized = await this.page.evaluate(checkElementLengthDifferentTo, e.unauthorized, 0) === true;
|
||||
const findUnauthorized = await this.hasElement(e.unauthorized);
|
||||
await this.logger('Check if Unauthorized message appears => ', findUnauthorized);
|
||||
return meteorStatusConfirm && getAudioButton && findUnauthorized;
|
||||
} catch (err) {
|
||||
@ -84,7 +83,7 @@ class Trigger extends Page {
|
||||
}, e.joinAudio)
|
||||
await this.logger('Check if Connections Buttons are disabled => ', getAudioButton);
|
||||
await sleep(3000);
|
||||
const findUnauthorized = await this.page.evaluate(checkElementLengthDifferentTo, e.unauthorized, 0) === true;
|
||||
const findUnauthorized = await this.hasElement(e.unauthorized);
|
||||
await this.logger('Check if Unauthorized message appears => ', findUnauthorized);
|
||||
return meteorStatusConfirm && getAudioButton && findUnauthorized;
|
||||
} catch (err) {
|
||||
|
@ -2,8 +2,8 @@ const Page = require('../core/page');
|
||||
const util = require('../chat/util');
|
||||
const utilUser = require('./util');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_TIME } = require('../core/constants');
|
||||
const { getElementLength, checkElementLengthEqualTo, checkElementLengthDifferentTo } = require('../core/util');
|
||||
const { ELEMENT_WAIT_TIME, ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { getElementLength, checkElementLengthEqualTo } = require('../core/util');
|
||||
|
||||
class MultiUsers {
|
||||
constructor() {
|
||||
@ -293,7 +293,7 @@ class MultiUsers {
|
||||
await this.page2.close();
|
||||
await utilUser.connectionStatus(this.page1);
|
||||
const connectionStatusItemEmpty = await this.page1.wasRemoved(e.connectionStatusItemEmpty);
|
||||
const connectionStatusOfflineUser = await this.page1.hasElement(e.connectionStatusOfflineUser, true);
|
||||
const connectionStatusOfflineUser = await this.page1.hasElement(e.connectionStatusOfflineUser, true, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
return connectionStatusItemEmpty && connectionStatusOfflineUser;
|
||||
} catch (err) {
|
||||
@ -313,13 +313,58 @@ class MultiUsers {
|
||||
}
|
||||
}
|
||||
|
||||
async usersConnectionStatus(testName) {
|
||||
try {
|
||||
await this.page1.shareWebcam(true);
|
||||
await this.page1.screenshot(testName, '01-page1-after-share-webcam');
|
||||
await this.initUserPage(false, testName);
|
||||
await this.userPage.joinMicrophone();
|
||||
await this.userPage.screenshot(testName, '02-userPage-after-join-microhpone');
|
||||
await this.userPage.shareWebcam(true);
|
||||
await this.userPage.screenshot(testName, '03-userPage-after-share-webcam');
|
||||
await this.userPage.waitAndClick(e.connectionStatusBtn);
|
||||
try {
|
||||
await this.userPage.page.waitForFunction(utilUser.checkNetworkStatus, { timeout: ELEMENT_WAIT_TIME },
|
||||
e.connectionDataContainer, e.connectionNetwordData
|
||||
);
|
||||
await this.userPage.screenshot(testName, '04-connection-network-success');
|
||||
return true;
|
||||
} catch (err) {
|
||||
await this.userPage.screenshot(testName, '04-connection-network-failed');
|
||||
this.userPage.logger(err);
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
this.page1.logger(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async disableWebcamsFromConnectionStatus() {
|
||||
try {
|
||||
await this.page1.shareWebcam(true, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.page2.shareWebcam(true, ELEMENT_WAIT_LONGER_TIME);
|
||||
await utilUser.connectionStatus(this.page1);
|
||||
await this.page1.waitAndClickElement(e.dataSavingWebcams);
|
||||
await this.page1.waitAndClickElement(e.closeConnectionStatusModal);
|
||||
await this.page1.waitForSelector(e.smallToastMsg);
|
||||
const checkUserWhoHasDisabled = await this.page1.page.evaluate(checkElementLengthEqualTo, e.videoContainer, 1);
|
||||
const checkSecondUser = await this.page2.page.evaluate(checkElementLengthEqualTo, e.videoContainer, 2);
|
||||
|
||||
return checkUserWhoHasDisabled && checkSecondUser;
|
||||
} catch (err) {
|
||||
await this.page1.logger(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async whiteboardNotAppearOnMobile() {
|
||||
try {
|
||||
await this.page1.waitAndClick(e.userListButton);
|
||||
await this.page2.waitAndClick(e.userListButton);
|
||||
await this.page2.waitAndClick(e.chatButtonKey);
|
||||
const onUserListPanel = await this.page1.isNotVisible(e.hidePresentation);
|
||||
const onChatPanel = await this.page2.isNotVisible(e.hidePresentation);
|
||||
const onUserListPanel = await this.page1.wasRemoved(e.hidePresentation);
|
||||
const onChatPanel = await this.page2.wasRemoved(e.hidePresentation);
|
||||
|
||||
return onUserListPanel && onChatPanel;
|
||||
} catch (err) {
|
||||
@ -333,7 +378,7 @@ class MultiUsers {
|
||||
await this.page2.waitAndClick(e.userListButton);
|
||||
await this.page2.waitAndClick(e.chatButtonKey);
|
||||
const whiteboard = await this.page1.page.evaluate(checkElementLengthEqualTo, e.chatButtonKey, 0);
|
||||
const onChatPanel = await this.page2.isNotVisible(e.chatButtonKey);
|
||||
const onChatPanel = await this.page2.hasElement(e.chatButtonKey, false);
|
||||
|
||||
return whiteboard && onChatPanel;
|
||||
} catch (err) {
|
||||
|
@ -2,10 +2,9 @@ const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const util = require('./util');
|
||||
const utilWebcam = require('../webcam/util');
|
||||
const utilScreenshare = require('../screenshare/util');
|
||||
const { sleep } = require('../core/helper');
|
||||
const { checkElementLengthEqualTo, checkElementLengthDifferentTo } = require('../core/util');
|
||||
const { checkElementLengthEqualTo } = require('../core/util');
|
||||
|
||||
class Status extends Page {
|
||||
constructor() {
|
||||
@ -15,12 +14,11 @@ class Status extends Page {
|
||||
async test() {
|
||||
try {
|
||||
await util.setStatus(this, e.applaud);
|
||||
const resp1 = await this.page.evaluate(checkElementLengthDifferentTo, e.applauseIcon, 0);
|
||||
const resp1 = await this.hasElement(e.applauseIcon);
|
||||
await sleep(1000);
|
||||
await util.setStatus(this, e.away);
|
||||
const resp2 = await this.page.evaluate(checkElementLengthDifferentTo, e.awayIcon, 0);
|
||||
const resp2 = await this.hasElement(e.awayIcon);
|
||||
|
||||
await this.waitAndClick(e.firstUser);
|
||||
await this.waitAndClick(e.clearStatus);
|
||||
return resp1 === resp2;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
@ -33,7 +31,7 @@ class Status extends Page {
|
||||
await this.waitAndClick(e.userList);
|
||||
await this.waitForSelector(e.firstUser);
|
||||
|
||||
const response = await this.page.evaluate(checkElementLengthDifferentTo, e.mobileUser, 0);
|
||||
const response = await this.hasElement(e.mobileUser);
|
||||
return response === true;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
@ -44,7 +42,7 @@ class Status extends Page {
|
||||
async findConnectionStatusModal() {
|
||||
try {
|
||||
await util.connectionStatus(this);
|
||||
const resp = await this.page.evaluate(checkElementLengthDifferentTo, e.connectionStatusModal, 0);
|
||||
const resp = await this.hasElement(e.connectionStatusModal);
|
||||
return resp === true;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
@ -52,21 +50,6 @@ class Status extends Page {
|
||||
}
|
||||
}
|
||||
|
||||
async disableWebcamsFromConnectionStatus() {
|
||||
try {
|
||||
await utilWebcam.enableWebcam(this, ELEMENT_WAIT_LONGER_TIME);
|
||||
await util.connectionStatus(this);
|
||||
await this.waitAndClickElement(e.dataSavingWebcams);
|
||||
await this.waitAndClickElement(e.closeConnectionStatusModal);
|
||||
await sleep(2000);
|
||||
const webcamsIsDisabledInDataSaving = await this.page.evaluate(checkElementLengthDifferentTo, e.webcamsIsDisabledInDataSaving, 0);
|
||||
return webcamsIsDisabledInDataSaving === true;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async disableScreenshareFromConnectionStatus() {
|
||||
try {
|
||||
await utilScreenshare.startScreenshare(this);
|
||||
@ -74,8 +57,8 @@ class Status extends Page {
|
||||
await util.connectionStatus(this);
|
||||
await this.waitAndClickElement(e.dataSavingScreenshare);
|
||||
await this.waitAndClickElement(e.closeConnectionStatusModal);
|
||||
await sleep(2000);
|
||||
const webcamsIsDisabledInDataSaving = await this.page.evaluate(checkElementLengthEqualTo, e.screenshareLocked, 0);
|
||||
|
||||
const webcamsIsDisabledInDataSaving = await this.hasElement(e.screenshareLocked);
|
||||
return webcamsIsDisabledInDataSaving === true;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
@ -87,13 +70,13 @@ class Status extends Page {
|
||||
try {
|
||||
await this.page.evaluate(() => window.dispatchEvent(new CustomEvent('socketstats', { detail: { rtt: 2000 } })));
|
||||
await this.joinMicrophone();
|
||||
await utilWebcam.enableWebcam(this, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.shareWebcam(true, ELEMENT_WAIT_LONGER_TIME);
|
||||
await utilScreenshare.startScreenshare(this);
|
||||
await utilScreenshare.waitForScreenshareContainer(this);
|
||||
await util.connectionStatus(this);
|
||||
await sleep(5000);
|
||||
const connectionStatusItemEmpty = await this.page.evaluate(checkElementLengthEqualTo, e.connectionStatusItemEmpty, 0);
|
||||
const connectionStatusItemUser = await this.page.evaluate(checkElementLengthDifferentTo, e.connectionStatusItemUser, 0);
|
||||
const connectionStatusItemUser = await this.hasElement(e.connectionStatusItemUser);
|
||||
return connectionStatusItemUser && connectionStatusItemEmpty;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
|
@ -112,22 +112,22 @@ const userTest = () => {
|
||||
// Open Connection Status Modal, start Webcam Share, disable Webcams in
|
||||
// Connection Status Modal and check if webcam sharing is still available
|
||||
test('Disable Webcams From Connection Status Modal', async () => {
|
||||
const test = new Status();
|
||||
const test = new MultiUsers();
|
||||
let response;
|
||||
let screenshot;
|
||||
try {
|
||||
const testName = 'disableWebcamsFromConnectionStatus';
|
||||
await test.logger('begin of ', testName);
|
||||
await test.init(true, true, testName);
|
||||
await test.startRecording(testName);
|
||||
await test.page1.logger('begin of ', testName);
|
||||
await test.init(testName);
|
||||
await test.page1.startRecording(testName);
|
||||
response = await test.disableWebcamsFromConnectionStatus();
|
||||
await test.stopRecording();
|
||||
screenshot = await test.page.screenshot();
|
||||
await test.logger('end of ', testName);
|
||||
await test.page1.stopRecording();
|
||||
screenshot = await test.page1.screenshot();
|
||||
await test.page1.logger('end of ', testName);
|
||||
} catch (err) {
|
||||
await test.logger(err);
|
||||
await test.page1.logger(err);
|
||||
} finally {
|
||||
await test.close();
|
||||
await test.close(test.page1, test.page2);
|
||||
}
|
||||
expect(response).toBe(true);
|
||||
Page.checkRegression(2.0, screenshot);
|
||||
@ -205,6 +205,29 @@ const userTest = () => {
|
||||
Page.checkRegression(2.0, screenshot);
|
||||
}, TEST_DURATION_TIME);
|
||||
|
||||
test('Show network data in Connection Status', async () => {
|
||||
const test = new MultiUsers();
|
||||
let response;
|
||||
let screenshot;
|
||||
try {
|
||||
const testName = 'connectionNetworkStatus';
|
||||
await test.page1.logger('begin of ', testName);
|
||||
await test.initMod1(testName);
|
||||
await test.page1.startRecording(testName);
|
||||
response = await test.usersConnectionStatus(testName);
|
||||
await test.page1.stopRecording();
|
||||
screenshot = await test.page1.page.screenshot();
|
||||
await test.page1.logger('end of ', testName);
|
||||
} catch (err) {
|
||||
await test.page1.logger(err);
|
||||
} finally {
|
||||
await test.close(test.page1, test.userPage);
|
||||
}
|
||||
expect(response).toBe(true);
|
||||
Page.checkRegression(2.0, screenshot);
|
||||
});
|
||||
|
||||
|
||||
// Raise and Lower Hand and make sure that the User2 Avatar color
|
||||
// and its avatar in raised hand toast are the same
|
||||
test('Raise Hand Toast', async () => {
|
||||
|
@ -11,5 +11,15 @@ async function connectionStatus(test) {
|
||||
await test.waitForSelector(e.connectionStatusModal);
|
||||
}
|
||||
|
||||
function checkNetworkStatus(dataContainer, networdData) {
|
||||
const values = Array.from(document.querySelectorAll(`${dataContainer} > ${networdData}`));
|
||||
values.splice(4, values.length - 4);
|
||||
const check = values.filter(e => e.textContent.includes(' 0 k'))[0];
|
||||
|
||||
if (!check) return true;
|
||||
}
|
||||
|
||||
|
||||
exports.setStatus = setStatus;
|
||||
exports.connectionStatus = connectionStatus;
|
||||
exports.checkNetworkStatus = checkNetworkStatus;
|
||||
|
@ -22,7 +22,7 @@ class Check extends Share {
|
||||
const parsedSettings = await this.getSettingsYaml();
|
||||
const videoPreviewTimeout = parseInt(parsedSettings.public.kurento.gUMTimeout);
|
||||
|
||||
await util.enableWebcam(this, videoPreviewTimeout);
|
||||
await this.shareWebcam(true, videoPreviewTimeout);
|
||||
const respUser = await util.webcamContentCheck(this);
|
||||
return respUser === true;
|
||||
} catch (err) {
|
||||
|
@ -1,7 +1,5 @@
|
||||
const Page = require('../core/page');
|
||||
const util = require('./util');
|
||||
const e = require('../core/elements');
|
||||
const { checkElementLengthDifferentTo } = require('../core/util');
|
||||
const { VIDEO_LOADING_WAIT_TIME } = require('../core/constants'); // core constants (Timeouts vars imported)
|
||||
|
||||
class Share extends Page {
|
||||
@ -13,8 +11,9 @@ class Share extends Page {
|
||||
try {
|
||||
const parsedSettings = await this.getSettingsYaml();
|
||||
const videoPreviewTimeout = parseInt(parsedSettings.public.kurento.gUMTimeout);
|
||||
const response = await util.enableWebcam(this, videoPreviewTimeout);
|
||||
return response;
|
||||
await this.shareWebcam(true, videoPreviewTimeout);
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
return false;
|
||||
@ -26,7 +25,7 @@ class Share extends Page {
|
||||
await this.joinMicrophone();
|
||||
const parsedSettings = await this.getSettingsYaml();
|
||||
const videoPreviewTimeout = parseInt(parsedSettings.public.kurento.gUMTimeout);
|
||||
await util.enableWebcam(this, videoPreviewTimeout);
|
||||
await this.shareWebcam(true, videoPreviewTimeout);
|
||||
} catch (err) {
|
||||
await this.logger(err);
|
||||
}
|
||||
@ -37,7 +36,7 @@ class Share extends Page {
|
||||
await this.waitForSelector(e.webcamVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
await this.waitForSelector(e.leaveVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
await this.waitForSelector(e.isTalking);
|
||||
const foundTestElement = await this.page.evaluate(checkElementLengthDifferentTo, e.webcamItemTalkingUser, 0);
|
||||
const foundTestElement = await this.hasElement(e.webcamItemTalkingUser);
|
||||
if (foundTestElement === true) {
|
||||
await this.screenshot(`${testName}`, `success-${testName}`);
|
||||
this.logger(testName, ' passed');
|
||||
|
@ -1,23 +1,11 @@
|
||||
const e = require('../core/elements');
|
||||
const { sleep } = require('../core/helper');
|
||||
const { checkElement, checkElementLengthDifferentTo } = require('../core/util');
|
||||
const { checkElement } = require('../core/util');
|
||||
const {
|
||||
LOOP_INTERVAL,
|
||||
VIDEO_LOADING_WAIT_TIME,
|
||||
ELEMENT_WAIT_LONGER_TIME,
|
||||
} = require('../core/constants');
|
||||
|
||||
async function enableWebcam(test, videoPreviewTimeout) {
|
||||
// Enabling webcam
|
||||
await test.waitAndClick(e.joinVideo);
|
||||
await test.waitForSelector(e.videoPreview, videoPreviewTimeout);
|
||||
await test.waitAndClick(e.startSharingWebcam);
|
||||
await test.waitForSelector(e.webcamConnecting);
|
||||
await test.waitForSelector(e.webcamVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
await test.waitForSelector(e.leaveVideo, VIDEO_LOADING_WAIT_TIME);
|
||||
return test.page.evaluate(checkElementLengthDifferentTo, e.webcamVideo, 0);
|
||||
}
|
||||
|
||||
async function evaluateCheck(test) {
|
||||
await test.waitForSelector(e.videoContainer);
|
||||
return test.page.evaluate(checkElement, e.presentationFullscreenButton, 1);
|
||||
@ -69,4 +57,3 @@ async function webcamContentCheck(test) {
|
||||
exports.startAndCheckForWebcams = startAndCheckForWebcams;
|
||||
exports.webcamContentCheck = webcamContentCheck;
|
||||
exports.evaluateCheck = evaluateCheck;
|
||||
exports.enableWebcam = enableWebcam;
|
||||
|
@ -19,7 +19,6 @@ const webcamTest = () => {
|
||||
const testName = 'shareWebcam';
|
||||
await test.logger('begin of ', testName);
|
||||
await test.init(true, true, testName);
|
||||
await test.closeAudioModal();
|
||||
await test.startRecording(testName);
|
||||
response = await test.test();
|
||||
await test.stopRecording();
|
||||
@ -42,7 +41,6 @@ const webcamTest = () => {
|
||||
const testName = 'checkWebcamContent';
|
||||
await test.logger('begin of ', testName);
|
||||
await test.init(true, true, testName);
|
||||
await test.closeAudioModal();
|
||||
await test.startRecording(testName);
|
||||
response = await test.test();
|
||||
await test.stopRecording();
|
||||
|
@ -1056,6 +1056,120 @@ class ApiController {
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************
|
||||
* LEARNING DASHBOARD DATA
|
||||
***********************************************/
|
||||
def learningDashboard = {
|
||||
String API_CALL = 'learningDashboard'
|
||||
log.debug CONTROLLER_NAME + "#${API_CALL}"
|
||||
|
||||
String respMessage = ""
|
||||
boolean reject = false
|
||||
|
||||
String sessionToken
|
||||
UserSession us
|
||||
Meeting meeting
|
||||
|
||||
Map.Entry<String, String> validationResponse = validateRequest(
|
||||
ValidationService.ApiCall.LEARNING_DASHBOARD,
|
||||
request.getParameterMap(),
|
||||
request.getQueryString(),
|
||||
)
|
||||
|
||||
//Validate Session
|
||||
if(!(validationResponse == null)) {
|
||||
respMessage = validationResponse.getValue()
|
||||
reject = true
|
||||
} else {
|
||||
sessionToken = sanitizeSessionToken(params.sessionToken)
|
||||
if (!hasValidSession(sessionToken)) {
|
||||
reject = true
|
||||
respMessage = "Invalid Session"
|
||||
}
|
||||
}
|
||||
|
||||
//Validate User
|
||||
if(reject == false) {
|
||||
us = getUserSession(sessionToken)
|
||||
|
||||
if(us == null) {
|
||||
reject = true;
|
||||
respMessage = "Access denied"
|
||||
} else if(!us.role.equals(ROLE_MODERATOR)) {
|
||||
reject = true
|
||||
respMessage = "Access denied"
|
||||
}
|
||||
}
|
||||
|
||||
//Validate Meeting
|
||||
if(reject == false) {
|
||||
meeting = meetingService.getMeeting(us.meetingID)
|
||||
boolean isRunning = meeting != null && meeting.isRunning();
|
||||
if(!isRunning) {
|
||||
reject = true
|
||||
respMessage = "Meeting not found"
|
||||
}
|
||||
|
||||
if(meeting.getLearningDashboardEnabled() == false) {
|
||||
reject = true
|
||||
respMessage = "Learning Dashboard disabled for this meeting"
|
||||
}
|
||||
}
|
||||
|
||||
//Validate File
|
||||
File jsonDataFile
|
||||
if(reject == false) {
|
||||
jsonDataFile = meetingService.learningDashboardService.getJsonDataFile(us.meetingID,meeting.getLearningDashboardAccessToken());
|
||||
if (!jsonDataFile.exists()) {
|
||||
reject = true
|
||||
respMessage = "Learning Dashboard data not found"
|
||||
}
|
||||
}
|
||||
|
||||
if (reject) {
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
withFormat {
|
||||
json {
|
||||
def builder = new JsonBuilder()
|
||||
builder.response {
|
||||
returncode RESP_CODE_FAILED
|
||||
message respMessage
|
||||
sessionToken
|
||||
}
|
||||
render(contentType: "application/json", text: builder.toPrettyString())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Map<String, Object> logData = new HashMap<String, Object>();
|
||||
logData.put("meetingid", us.meetingID);
|
||||
logData.put("extMeetingid", us.externMeetingID);
|
||||
logData.put("name", us.fullname);
|
||||
logData.put("userid", us.internalUserId);
|
||||
logData.put("sessionToken", sessionToken);
|
||||
logData.put("logCode", "learningDashboard");
|
||||
logData.put("description", "Request Learning Dashboard data.");
|
||||
|
||||
Gson gson = new Gson();
|
||||
String logStr = gson.toJson(logData);
|
||||
|
||||
log.info(" --analytics-- data=" + logStr);
|
||||
|
||||
response.addHeader("Cache-Control", "no-cache")
|
||||
|
||||
withFormat {
|
||||
json {
|
||||
def builder = new JsonBuilder()
|
||||
builder.response {
|
||||
returncode RESP_CODE_SUCCESS
|
||||
data jsonDataFile.getText()
|
||||
sessionToken
|
||||
}
|
||||
render(contentType: "application/json", text: builder.toPrettyString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def uploadDocuments(conf) { //
|
||||
log.debug("ApiController#uploadDocuments(${conf.getInternalId()})");
|
||||
|
||||
|
@ -151,6 +151,30 @@
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "learningDashboard",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{path}}/learningDashboard?{{param_session_token}}=",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{path}}",
|
||||
"learningDashboard"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "{{param_session_token}}",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
}
|
@ -1,3 +1,11 @@
|
||||
location @html5client {
|
||||
# proxy_pass http://127.0.0.1:4100; # use for development
|
||||
proxy_pass http://poolhtml5servers; # use for production
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
}
|
||||
|
||||
location /html5client/locales {
|
||||
alias /usr/share/meteor/bundle/programs/web.browser/app/locales;
|
||||
}
|
||||
@ -18,10 +26,15 @@ location /html5client/fonts {
|
||||
alias /usr/share/meteor/bundle/programs/web.browser/app/fonts;
|
||||
}
|
||||
|
||||
location ~ ^/html5client/ {
|
||||
# proxy_pass http://127.0.0.1:4100; # use for development
|
||||
proxy_pass http://poolhtml5servers; # use for production
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
location /html5client/wasm {
|
||||
types {
|
||||
application/wasm wasm;
|
||||
}
|
||||
gzip_static on;
|
||||
alias /usr/share/meteor/bundle/programs/web.browser/app/wasm;
|
||||
}
|
||||
|
||||
location /html5client {
|
||||
alias /usr/share/meteor/bundle/programs/web.browser;
|
||||
try_files $uri @html5client;
|
||||
}
|
||||
|
@ -91,6 +91,16 @@ if [ -f staging/usr/share/meteor/bundle/programs/web.browser/head.html ]; then
|
||||
sed -i "s/VERSION/$(($BUILD))/" staging/usr/share/meteor/bundle/programs/web.browser/head.html
|
||||
fi
|
||||
|
||||
# Compress tensorflow WASM binaries used for virtual backgrounds. Keep the
|
||||
# uncompressed versions as well so it works with mismatched nginx location blocks
|
||||
if [ -f staging/usr/share/meteor/bundle/programs/web.browser/app/wasm/tflite-simd.wasm ]; then
|
||||
gzip -k -f -9 staging/usr/share/meteor/bundle/programs/web.browser/app/wasm/tflite-simd.wasm
|
||||
fi
|
||||
|
||||
if [ -f staging/usr/share/meteor/bundle/programs/web.browser/app/wasm/tflite.wasm ]; then
|
||||
gzip -k -f -9 staging/usr/share/meteor/bundle/programs/web.browser/app/wasm/tflite.wasm
|
||||
fi
|
||||
|
||||
mkdir -p staging/etc/nginx/sites-available
|
||||
cp bigbluebutton.nginx staging/etc/nginx/sites-available/bigbluebutton
|
||||
|
||||
|
@ -143,7 +143,7 @@ module BigBlueButton
|
||||
|
||||
ffmpeg_filter << ",atempo=#{speed},atrim=start=#{ms_to_s(audio[:timestamp])}" if speed != 1
|
||||
|
||||
ffmpeg_filter << ",asetpts=PTS-STARTPTS"
|
||||
ffmpeg_filter << ",asetpts=N"
|
||||
else
|
||||
BigBlueButton.logger.info " Generating silence"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user