mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
RTC-5104: screensharing indicator (#536)
* RTC-5104: screensharing indicator * RTC-5104: screensharing indicator, windows fixes
This commit is contained in:
committed by
Vishwas Shashidhar
parent
4832c28dd2
commit
9609bc7976
@@ -83,9 +83,9 @@
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Get Media Sources:</p>
|
<p>Get Media Sources:</p>
|
||||||
<button id='get-sources'>Open screen picker</button>
|
<button id='get-sources'>Open screen picker & screensharing indicator</button>
|
||||||
<br>
|
<br>
|
||||||
<video id='video'></video>
|
<video id='video' autoPlay loop muted style='max-width: 640px'></video>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Get Version Info:</p>
|
<p>Get Version Info:</p>
|
||||||
@@ -226,8 +226,8 @@
|
|||||||
var getSources = document.getElementById('get-sources');
|
var getSources = document.getElementById('get-sources');
|
||||||
getSources.addEventListener('click', function() {
|
getSources.addEventListener('click', function() {
|
||||||
ssf.getMediaSource({types: ['window', 'screen']}, function(error, source) {
|
ssf.getMediaSource({types: ['window', 'screen']}, function(error, source) {
|
||||||
if (error) throw error
|
if (error) throw error;
|
||||||
navigator.webkitGetUserMedia({
|
navigator.webkitGetUserMedia({
|
||||||
audio: false,
|
audio: false,
|
||||||
video: {
|
video: {
|
||||||
mandatory: {
|
mandatory: {
|
||||||
@@ -239,12 +239,24 @@
|
|||||||
maxHeight: 720
|
maxHeight: 720
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, handleStream, handleError)
|
}, stream => {
|
||||||
|
handleStream(stream, source.display_id);
|
||||||
|
}, handleError)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleStream (stream) {
|
function handleStream(stream, displayId) {
|
||||||
document.querySelector('video').src = URL.createObjectURL(stream)
|
document.getElementById('video').srcObject = stream;
|
||||||
|
ssf.showScreenSharingIndicator({
|
||||||
|
stream,
|
||||||
|
displayId
|
||||||
|
}, function(event) {
|
||||||
|
console.log('screen-sharing-indicator callback', event);
|
||||||
|
if (event.type === 'stopRequested') {
|
||||||
|
stream.getVideoTracks().forEach(t => t.stop());
|
||||||
|
document.getElementById('video').srcObject = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleError (e) {
|
function handleError (e) {
|
||||||
|
@@ -25,6 +25,7 @@ const cmds = keyMirror({
|
|||||||
setIsInMeeting: null,
|
setIsInMeeting: null,
|
||||||
setLocale: null,
|
setLocale: null,
|
||||||
keyPress: null,
|
keyPress: null,
|
||||||
|
openScreenSharingIndicator: null
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@@ -17,6 +17,7 @@ const { bringToFront } = require('./bringToFront.js');
|
|||||||
const eventEmitter = require('./eventEmitter');
|
const eventEmitter = require('./eventEmitter');
|
||||||
const { isMac } = require('./utils/misc');
|
const { isMac } = require('./utils/misc');
|
||||||
const { openScreenPickerWindow } = require('./desktopCapturer');
|
const { openScreenPickerWindow } = require('./desktopCapturer');
|
||||||
|
const { openScreenSharingIndicator } = require('./screenSharingIndicator');
|
||||||
const { setPreloadMemoryInfo, setIsInMeeting, setPreloadWindow } = require('./memoryMonitor');
|
const { setPreloadMemoryInfo, setIsInMeeting, setPreloadWindow } = require('./memoryMonitor');
|
||||||
|
|
||||||
const apiEnums = require('./enums/api.js');
|
const apiEnums = require('./enums/api.js');
|
||||||
@@ -179,6 +180,11 @@ electron.ipcMain.on(apiName, (event, arg) => {
|
|||||||
windowMgr.handleKeyPress(arg.keyCode);
|
windowMgr.handleKeyPress(arg.keyCode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case apiCmds.openScreenSharingIndicator:
|
||||||
|
if (typeof arg.displayId === 'string' && typeof arg.id === 'number') {
|
||||||
|
openScreenSharingIndicator(event.sender, arg.displayId, arg.id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ const apiCmds = apiEnums.cmds;
|
|||||||
const apiName = apiEnums.apiName;
|
const apiName = apiEnums.apiName;
|
||||||
const getMediaSources = require('../desktopCapturer/getSources');
|
const getMediaSources = require('../desktopCapturer/getSources');
|
||||||
const getMediaSource = require('../desktopCapturer/getSource');
|
const getMediaSource = require('../desktopCapturer/getSource');
|
||||||
|
const showScreenSharingIndicator = require('../screenSharingIndicator/showScreenSharingIndicator');
|
||||||
const { TitleBar } = require('../windowsTitlebar');
|
const { TitleBar } = require('../windowsTitlebar');
|
||||||
const titleBar = new TitleBar();
|
const titleBar = new TitleBar();
|
||||||
const { buildNumber } = require('../../package.json');
|
const { buildNumber } = require('../../package.json');
|
||||||
@@ -317,6 +318,20 @@ function createAPI() {
|
|||||||
*/
|
*/
|
||||||
getMediaSource: getMediaSource,
|
getMediaSource: getMediaSource,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a banner that informs user that the screen is being shared.
|
||||||
|
*
|
||||||
|
* @param params object with following fields:
|
||||||
|
* - stream https://developer.mozilla.org/en-US/docs/Web/API/MediaStream/MediaStream object.
|
||||||
|
* The indicator automatically destroys itself when stream becomes inactive (see MediaStream.active).
|
||||||
|
* - displayId id of the display that is being shared or that contains the shared app
|
||||||
|
* @param callback callback function that will be called to handle events.
|
||||||
|
* Callback receives event object { type: string }. Types:
|
||||||
|
* - 'error' - error occured. Event object contains 'reason' field.
|
||||||
|
* - 'stopRequested' - user clicked "Stop Sharing" button.
|
||||||
|
*/
|
||||||
|
showScreenSharingIndicator: showScreenSharingIndicator,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a modal window to configure notification preference.
|
* Opens a modal window to configure notification preference.
|
||||||
*/
|
*/
|
||||||
|
104
js/screenSharingIndicator/index.js
Executable file
104
js/screenSharingIndicator/index.js
Executable file
@@ -0,0 +1,104 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const ipcMain = electron.ipcMain;
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
const { isMac } = require('./../utils/misc.js');
|
||||||
|
|
||||||
|
const baseWindowConfig = {
|
||||||
|
width: 592,
|
||||||
|
height: 48,
|
||||||
|
show: false,
|
||||||
|
modal: true,
|
||||||
|
frame: false,
|
||||||
|
focusable: false,
|
||||||
|
transparent: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
resizable: false,
|
||||||
|
minimizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
closable: true,
|
||||||
|
alwaysOnTop: true,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'renderer.js'),
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false,
|
||||||
|
devTools: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getTemplatePath() {
|
||||||
|
let templatePath = path.join(__dirname, 'screen-sharing-indicator.html');
|
||||||
|
try {
|
||||||
|
fs.statSync(templatePath).isFile();
|
||||||
|
} catch (err) {
|
||||||
|
log.send(logLevels.ERROR, `screen-sharing-indicator: Could not find template ("${templatePath}").`);
|
||||||
|
}
|
||||||
|
return `file://${templatePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openScreenSharingIndicator(eventSender, displayId, id) {
|
||||||
|
const indicatorScreen = (displayId && electron.screen.getAllDisplays().filter(d => displayId.includes(d.id))[0]) || electron.screen.getPrimaryDisplay();
|
||||||
|
const screenRect = indicatorScreen.workArea;
|
||||||
|
const windowConfig = Object.assign({}, baseWindowConfig, {
|
||||||
|
x: screenRect.x + Math.round((screenRect.width - baseWindowConfig.width) / 2),
|
||||||
|
y: screenRect.y + screenRect.height - baseWindowConfig.height
|
||||||
|
});
|
||||||
|
|
||||||
|
const indicatorWindow = new electron.BrowserWindow(windowConfig);
|
||||||
|
indicatorWindow.setVisibleOnAllWorkspaces(true);
|
||||||
|
indicatorWindow.setMenu(null);
|
||||||
|
indicatorWindow.loadURL(getTemplatePath());
|
||||||
|
|
||||||
|
indicatorWindow.once('ready-to-show', () => {
|
||||||
|
indicatorWindow.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
indicatorWindow.webContents.on('did-finish-load', () => {
|
||||||
|
initCrashReporterMain({ process: 'screen sharing indicator window' });
|
||||||
|
initCrashReporterRenderer(indicatorWindow, { process: 'render | screen sharing indicator window' });
|
||||||
|
indicatorWindow.webContents.send('window-data', {
|
||||||
|
id,
|
||||||
|
i18n: i18n.getMessageFor('ScreenSharingIndicator'),
|
||||||
|
isMac
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
indicatorWindow.webContents.on('crashed', () => {
|
||||||
|
const errorDialogOptions = {
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor('Renderer Process Crashed'),
|
||||||
|
message: i18n.getMessageFor('Oops! Looks like we have had a crash.'),
|
||||||
|
buttons: ['Close']
|
||||||
|
};
|
||||||
|
electron.dialog.showMessageBox(errorDialogOptions, () => indicatorWindow.close());
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleStopSharingClicked = (event, indicatorId) => {
|
||||||
|
if (indicatorId === id) {
|
||||||
|
eventSender.send('stop-sharing-requested', id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDestroyScreensharingIndicator = (event, indicatorId) => {
|
||||||
|
if (indicatorId === id) {
|
||||||
|
if (!indicatorWindow.isDestroyed()) {
|
||||||
|
indicatorWindow.close();
|
||||||
|
}
|
||||||
|
ipcMain.removeListener('stop-sharing-clicked', handleStopSharingClicked);
|
||||||
|
ipcMain.removeListener('destroy-screensharing-indicator', handleDestroyScreensharingIndicator);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ipcMain.on('stop-sharing-clicked', handleStopSharingClicked);
|
||||||
|
ipcMain.on('destroy-screensharing-indicator', handleDestroyScreensharingIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openScreenSharingIndicator
|
||||||
|
};
|
38
js/screenSharingIndicator/renderer.js
Normal file
38
js/screenSharingIndicator/renderer.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { ipcRenderer, crashReporter } = require('electron');
|
||||||
|
|
||||||
|
let indicatorId;
|
||||||
|
|
||||||
|
function renderDom() {
|
||||||
|
const stopSharingButton = document.getElementById('stop-sharing-button');
|
||||||
|
stopSharingButton.addEventListener('click', () => {
|
||||||
|
ipcRenderer.send('stop-sharing-clicked', indicatorId);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
const hideButton = document.getElementById('hide-button');
|
||||||
|
hideButton.addEventListener('click', () => {
|
||||||
|
window.close();
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.on('window-data', (event, content) => {
|
||||||
|
indicatorId = content.id;
|
||||||
|
const setText = (el, text) => {
|
||||||
|
document.getElementById(el).innerHTML = (content.i18n[text] || text).replace('Symphony', '<b>Symphony</b>');
|
||||||
|
};
|
||||||
|
setText('stop-sharing-button', 'Stop sharing');
|
||||||
|
setText('hide-button', 'Hide');
|
||||||
|
setText('text-label', 'You are sharing your screen on Symphony');
|
||||||
|
document.body.className = content.isMac ? 'mac' : '';
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
||||||
|
if (arg && typeof arg === 'object') {
|
||||||
|
crashReporter.start(arg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
renderDom();
|
||||||
|
});
|
104
js/screenSharingIndicator/screen-sharing-indicator.html
Executable file
104
js/screenSharingIndicator/screen-sharing-indicator.html
Executable file
@@ -0,0 +1,104 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title data-i18n-text="Screen Sharing"></title>
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: system;
|
||||||
|
font-style: normal;
|
||||||
|
src: local(".SFNSText"), local(".HelveticaNeueDeskInterface"), local("Ubuntu Light"), local("Segoe UI"), local("Roboto"), local("Tahoma");
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "system";
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
background: rgba(255, 255, 255, 0.94);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body:not(.mac) .container {
|
||||||
|
border: 1px solid rgb(212, 212, 212);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
float: right;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stop-sharing-button {
|
||||||
|
text-transform: uppercase;
|
||||||
|
background: #107ccc;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
font-size: inherit;
|
||||||
|
border-radius: 14px;
|
||||||
|
height: 28px;
|
||||||
|
padding: 6px 14px;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hide-button {
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #6b717c;
|
||||||
|
margin-right: 29px;
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text-label {
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
left: 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#drag-area {
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 22px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
0deg,
|
||||||
|
rgba(0, 0, 0, 0),
|
||||||
|
rgba(0, 0, 0, 0) 1px,
|
||||||
|
rgba(0, 0, 0, 0.22) 1px,
|
||||||
|
rgba(0, 0, 0, 0.22) 2px
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mac #hide-button {
|
||||||
|
color: #303237;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mac #stop-sharing-button {
|
||||||
|
padding: 6px 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<span id='drag-area'></span>
|
||||||
|
<span id='text-label'>You are sharing your screen on <b>Symphony</b></span>
|
||||||
|
<span class='buttons'>
|
||||||
|
<a id='hide-button' href='#'>Hide</a>
|
||||||
|
<button id='stop-sharing-button'>Stop sharing</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
46
js/screenSharingIndicator/showScreenSharingIndicator.js
Normal file
46
js/screenSharingIndicator/showScreenSharingIndicator.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
const apiEnums = require('../enums/api.js');
|
||||||
|
const apiCmds = apiEnums.cmds;
|
||||||
|
const apiName = apiEnums.apiName;
|
||||||
|
|
||||||
|
let nextIndicatorId = 0;
|
||||||
|
|
||||||
|
function showScreenSharingIndicator(options, callback) {
|
||||||
|
const { stream, displayId } = options;
|
||||||
|
|
||||||
|
if (!stream || !stream.active || stream.getVideoTracks().length !== 1) {
|
||||||
|
callback({type: 'error', reason: 'bad stream'});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (displayId && typeof(displayId) !== 'string') {
|
||||||
|
callback({type: 'error', reason: 'bad displayId'});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = ++nextIndicatorId;
|
||||||
|
ipcRenderer.send(apiName, {
|
||||||
|
cmd: apiCmds.openScreenSharingIndicator,
|
||||||
|
displayId: options.displayId,
|
||||||
|
id
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleStopRequest = (e, indicatorId) => {
|
||||||
|
if (indicatorId === id) {
|
||||||
|
callback({type: 'stopRequested'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const destroy = () => {
|
||||||
|
ipcRenderer.send('destroy-screensharing-indicator', id);
|
||||||
|
options.stream.removeEventListener('inactive', destroy);
|
||||||
|
ipcRenderer.removeListener('stop-sharing-requested', handleStopRequest);
|
||||||
|
};
|
||||||
|
|
||||||
|
ipcRenderer.on('stop-sharing-requested', handleStopRequest);
|
||||||
|
options.stream.addEventListener('inactive', destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = showScreenSharingIndicator;
|
@@ -111,6 +111,11 @@
|
|||||||
"Select Screen": "Select Screen",
|
"Select Screen": "Select Screen",
|
||||||
"Share": "Share"
|
"Share": "Share"
|
||||||
},
|
},
|
||||||
|
"ScreenSharingIndicator": {
|
||||||
|
"You are sharing your screen on Symphony": "You are sharing your screen on Symphony",
|
||||||
|
"Stop sharing": "Stop sharing",
|
||||||
|
"Hide": "Hide"
|
||||||
|
},
|
||||||
"ScreenSnippet": {
|
"ScreenSnippet": {
|
||||||
"Done": "Done",
|
"Done": "Done",
|
||||||
"Erase": "Erase",
|
"Erase": "Erase",
|
||||||
|
@@ -109,6 +109,11 @@
|
|||||||
"Select Screen": "Select Screen",
|
"Select Screen": "Select Screen",
|
||||||
"Share": "Share"
|
"Share": "Share"
|
||||||
},
|
},
|
||||||
|
"ScreenSharingIndicator": {
|
||||||
|
"You are sharing your screen on Symphony": "You are sharing your screen on Symphony",
|
||||||
|
"Stop sharing": "Stop sharing",
|
||||||
|
"Hide": "Hide"
|
||||||
|
},
|
||||||
"ScreenSnippet": {
|
"ScreenSnippet": {
|
||||||
"Done": "Done",
|
"Done": "Done",
|
||||||
"Erase": "Erase",
|
"Erase": "Erase",
|
||||||
|
@@ -109,6 +109,11 @@
|
|||||||
"Select Screen":"Sélectionnez l'écran",
|
"Select Screen":"Sélectionnez l'écran",
|
||||||
"Share":"Partager"
|
"Share":"Partager"
|
||||||
},
|
},
|
||||||
|
"ScreenSharingIndicator": {
|
||||||
|
"You are sharing your screen on Symphony": "Vous partagez votre écran sur Symphony",
|
||||||
|
"Stop sharing": "Arrêter le partage",
|
||||||
|
"Hide": "Masquer"
|
||||||
|
},
|
||||||
"ScreenSnippet":{
|
"ScreenSnippet":{
|
||||||
"Done":"Terminé",
|
"Done":"Terminé",
|
||||||
"Erase":"Effacer",
|
"Erase":"Effacer",
|
||||||
|
@@ -109,6 +109,11 @@
|
|||||||
"Select Screen":"Sélectionnez l'écran",
|
"Select Screen":"Sélectionnez l'écran",
|
||||||
"Share":"Partager"
|
"Share":"Partager"
|
||||||
},
|
},
|
||||||
|
"ScreenSharingIndicator": {
|
||||||
|
"You are sharing your screen on Symphony": "Vous partagez votre écran sur Symphony",
|
||||||
|
"Stop sharing": "Arrêter le partage",
|
||||||
|
"Hide": "Masquer"
|
||||||
|
},
|
||||||
"ScreenSnippet":{
|
"ScreenSnippet":{
|
||||||
"Done":"Terminé",
|
"Done":"Terminé",
|
||||||
"Erase":"Effacer",
|
"Erase":"Effacer",
|
||||||
|
@@ -111,6 +111,11 @@
|
|||||||
"Select Screen": "画面を選択",
|
"Select Screen": "画面を選択",
|
||||||
"Share": "共有"
|
"Share": "共有"
|
||||||
},
|
},
|
||||||
|
"ScreenSharingIndicator": {
|
||||||
|
"You are sharing your screen on Symphony": "あなたはSymphony上であなたの画面を共有しています",
|
||||||
|
"Stop Sharing": "共有を停止",
|
||||||
|
"Hide": "非表示にする"
|
||||||
|
},
|
||||||
"ScreenSnippet": {
|
"ScreenSnippet": {
|
||||||
"Done": "完了",
|
"Done": "完了",
|
||||||
"Erase": "消去",
|
"Erase": "消去",
|
||||||
|
@@ -109,6 +109,11 @@
|
|||||||
"Select Screen": "画面を選択",
|
"Select Screen": "画面を選択",
|
||||||
"Share": "共有"
|
"Share": "共有"
|
||||||
},
|
},
|
||||||
|
"ScreenSharingIndicator": {
|
||||||
|
"You are sharing your screen on Symphony": "あなたはSymphony上であなたの画面を共有しています",
|
||||||
|
"Stop Sharing": "共有を停止",
|
||||||
|
"Hide": "非表示にする"
|
||||||
|
},
|
||||||
"ScreenSnippet": {
|
"ScreenSnippet": {
|
||||||
"Done": "完了",
|
"Done": "完了",
|
||||||
"Erase": "消去",
|
"Erase": "消去",
|
||||||
|
Reference in New Issue
Block a user