12 Commits

Author SHA1 Message Date
Lukas F. Hartmann
386d784952 touch: fix vector transforming (points of arrows, scribbles) 2020-12-18 18:11:33 +01:00
Lukas F. Hartmann
352b01569f touch: fix media upload on iDevice 2020-12-18 17:36:44 +01:00
Lukas F. Hartmann
82515e3a8e touch (tablet): fix deselect when tapping space; add edit text button 2020-12-18 17:07:32 +01:00
Lukas F. Hartmann
16e926b76a nuke some leftover traces of googlefonts 2020-11-24 20:15:13 +01:00
mntmn
0e97945b95 Merge branch 'mnt' of github.com:spacedeck/spacedeck-open into mnt 2020-11-23 12:25:56 +01:00
mntmn
581ee8eb04 Merge branch 'arillo-feature/video-native-timeline' into mnt 2020-11-23 12:24:30 +01:00
mntmn
c1e29fb7e2 Merge branch 'feature/video-native-timeline' of https://github.com/arillo/spacedeck-open into arillo-feature/video-native-timeline 2020-11-23 12:23:10 +01:00
Julian David
447076845c Add ISSUE_TEMPLATE.md (#139)
Co-authored-by: julian.mora <julian.mora@bizagi.com>
2020-11-23 12:12:54 +01:00
Christian
a051fc4e6f Create nginx_setup.md (#138) 2020-11-23 12:12:35 +01:00
banglashi
5a7839ceaa allow to lock own artefacts as an editor (#132)
* allow to lock own artefacts as an editor
2020-11-23 12:10:35 +01:00
DM
26f4da68ea show native video controls when playing 2020-11-23 11:56:02 +01:00
mntmn
c9b6e7c2c8 Merge pull request #137 from spacedeck/remove-cdns
Replace google fonts include with locally hosted Inter font
2020-11-21 20:42:28 +01:00
15 changed files with 205 additions and 131 deletions

20
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,20 @@
## Expected Behavior
## Actual Behavior
## Possible Solution
## Steps to Reproduce the Problem
1.
2.
3.
## Specifications
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04):
- Node version:
- Database engine (e.g., SQLite):

53
docs/nginx_setup.md Normal file
View File

@@ -0,0 +1,53 @@
# Nginx as reverse proxy
Below theres an example of how the site configuration for nginx as a reverse proxy can look like:
```
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
servername spacedeck.domain.de
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl on;
server_name spacedeck.domain.de;
ssl_certificate /etc/ssl/spacedeck.domain.de.cer;
ssl_certificate_key /etc/ssl/spacedeck.domain.de.key;
include ssl_params;
charset utf-8;
client_max_body_size 50m;
add_header Content-Security-Policy "default-src https: wss:; script-src https: 'unsafe-inline' 'unsafe-eval'; style-src https: 'unsafe-inline'";
add_header X-XSS-Protection "1; mode=block;";
add_header Referrer-Policy "no-referrer";
location / {
proxy_pass http://127.0.0.1:9666;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /socket {
proxy_pass http://127.0.0.1:9666;
proxy_set_header Connection 'upgrade';
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```

View File

@@ -103,7 +103,7 @@ function render_space_as_html(space, artifacts) {
walk(dom("#space")[0],0); walk(dom("#space")[0],0);
//console.log("compiled template: \n"+compiled_js); //console.log("compiled template: \n"+compiled_js);
} }
// -------- // --------
var mouse_state = "idle"; var mouse_state = "idle";
var active_tool = "pointer"; var active_tool = "pointer";
@@ -136,14 +136,13 @@ function render_space_as_html(space, artifacts) {
} catch (e) { } catch (e) {
console.error("error rendering space "+space._id+" as html: "+e); console.error("error rendering space "+space._id+" as html: "+e);
} }
var style="html, body, #space { overflow: visible !important; }\n"; var style="html, body, #space { overflow: visible !important; }\n";
style+=".wrapper { border: none !important; }\n"; style+=".wrapper { border: none !important; }\n";
h='<html>\n<head>\n<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,700,600,800,300|Montserrat:400,700|EB+Garamond|Vollkorn|Fire+Sans|Lato|Roboto|Source+Code+Pro|Ubuntu|Raleway|Playfair+Display|Crimson+Text" rel="stylesheet" type="text/css">\n<link type="text/css" rel="stylesheet" href="https://fast.fonts.net/cssapi/ee1a3484-4d98-4f9f-9f55-020a7b37f3c5.css"/>\n<link rel="stylesheet" href="/stylesheets/style.css"><style>'+style+'</style>\n</head>\n<body id="main">\n'+h+"\n</html>\n"; h='<html>\n<head>\n<link rel="stylesheet" href="/stylesheets/style.css"><style>'+style+'</style>\n</head>\n<body id="main">\n'+h+"\n</html>\n";
return h; return h;
} }
exports.render_space_as_html = render_space_as_html; exports.render_space_as_html = render_space_as_html;

View File

@@ -322,6 +322,7 @@
"follow_present": "Follow", "follow_present": "Follow",
"mute_present": "Unfollow", "mute_present": "Unfollow",
"follow_present_help": "If someone else is presenting this Space, the other members automatically follow the presentation. Switch following on or off with this button.", "follow_present_help": "If someone else is presenting this Space, the other members automatically follow the presentation. Switch following on or off with this button.",
"export": "export", "export": "Export",
"media": "Media" "media": "Media",
} "tool_edit_text": "Edit Text"
}

View File

@@ -52,9 +52,18 @@ function setup_directives() {
} }
var play_func = function() { var play_func = function() {
video.play(); var playPromise = video.play();
player_state = "playing"; if (playPromise !== undefined) {
update_view(); playPromise.then(_ => {
// Automatic playback started!
player_state = "playing";
update_view();
})
.catch(error => {
// Auto-play was prevented
// Show paused UI.
});
}
} }
var pause_func = function() { var pause_func = function() {

View File

@@ -182,7 +182,8 @@ var SpacedeckSections = {
toolbar_props_in: false, toolbar_props_in: false,
toolbar_artifacts_x: "-1000px", toolbar_artifacts_x: "-1000px",
toolbar_artifacts_y: "-1000px", toolbar_artifacts_y: "-1000px",
toolbar_artifacts_in: true toolbar_artifacts_in: true,
toolbar_lock_in: false
}, },
methods: { methods: {
@@ -848,7 +849,7 @@ var SpacedeckSections = {
if (!a) return false; if (!a) return false;
if (!this.active_space) return false; if (!this.active_space) return false;
if (this.active_space_role=="viewer" || (a.locked && this.active_space_role!="admin")) { if (this.active_space_role=="viewer" || (a.locked && this.active_space_role=="viewer")) {
return false; return false;
} }
@@ -1018,8 +1019,7 @@ var SpacedeckSections = {
}; };
}, },
update_selection_metrics: function(arts) { update_selection_metrics: function(arts, temporary) {
if (this.active_tool == "scribble") { if (this.active_tool == "scribble") {
this.selection_metrics.count = 1; this.selection_metrics.count = 1;
return; return;
@@ -1052,8 +1052,6 @@ var SpacedeckSections = {
// FIXME make sure that menus fit in window // FIXME make sure that menus fit in window
this.toolbar_props_x = pp.x+"px"; this.toolbar_props_x = pp.x+"px";
this.toolbar_props_y = pp.y+"px"; this.toolbar_props_y = pp.y+"px";
//this.hide_toolbar_artifacts();
} }
this.selection_metrics.x1 = sr.x1; this.selection_metrics.x1 = sr.x1;
@@ -1068,24 +1066,26 @@ var SpacedeckSections = {
if (!arts) arts = this.selected_artifacts(); if (!arts) arts = this.selected_artifacts();
this.first_selected_artifact = arts[0]; if (!temporary) {
this.selection_metrics.count=arts.length; this.first_selected_artifact = arts[0];
this.selection_metrics.scribble_selection = false; this.selection_metrics.count=arts.length;
if (arts.length == 1 && arts[0].mime == "x-spacedeck/vector") { this.selection_metrics.scribble_selection = false;
if (arts[0].shape == "scribble") { if (arts.length == 1 && arts[0].mime == "x-spacedeck/vector") {
this.selection_metrics.scribble_selection = true; if (arts[0].shape == "scribble") {
this.selection_metrics.scribble_selection = true;
}
this.selection_metrics.vector_points = arts[0].control_points;
this.selection_metrics.vector_selection = true;
} else {
this.selection_metrics.vector_points = [{},{}];
this.selection_metrics.vector_selection = false;
}
this.selection_metrics.has_link=false;
this.insert_link_url="";
if (arts.length == 1 && arts[0].meta && arts[0].meta.link_uri && arts[0].meta.link_uri.length>0) {
this.selection_metrics.has_link=true;
this.insert_link_url = arts[0].meta.link_uri;
} }
this.selection_metrics.vector_points = arts[0].control_points;
this.selection_metrics.vector_selection = true;
} else {
this.selection_metrics.vector_points = [{},{}];
this.selection_metrics.vector_selection = false;
}
this.selection_metrics.has_link=false;
this.insert_link_url="";
if (arts.length == 1 && arts[0].meta && arts[0].meta.link_uri && arts[0].meta.link_uri.length>0) {
this.selection_metrics.has_link=true;
this.insert_link_url = arts[0].meta.link_uri;
} }
}, },
@@ -1435,13 +1435,13 @@ var SpacedeckSections = {
this.color_picker_rgb = rgb_to_hex(rgba.r,rgba.g,rgba.b); this.color_picker_rgb = rgb_to_hex(rgba.r,rgba.g,rgba.b);
}, },
update_selected_artifacts: function(change_func, override_locked) { update_selected_artifacts: function(change_func, override_locked, temporary) {
var artifacts = this.selected_artifacts(!override_locked); var artifacts = this.selected_artifacts(!override_locked);
if (!artifacts.length) return; if (!artifacts.length) return;
this.update_artifacts(artifacts, change_func); this.update_artifacts(artifacts, change_func);
this.update_selection_metrics(); this.update_selection_metrics(null, temporary||false);
}, },
nudge_selected_artifacts: function(dx, dy, event) { nudge_selected_artifacts: function(dx, dy, event) {
@@ -1922,10 +1922,7 @@ var SpacedeckSections = {
}.bind(this)); }.bind(this));
}, },
delayed_edit_artifact: function(evt) { delayed_edit_artifact: function() {
evt.stopPropagation();
evt.preventDefault();
var a = this.selected_artifacts()[0]; var a = this.selected_artifacts()[0];
var el = $("#ios-focuser-"+a._id); var el = $("#ios-focuser-"+a._id);
@@ -2086,8 +2083,6 @@ var SpacedeckSections = {
if (a.description!=dom.innerHTML) { if (a.description!=dom.innerHTML) {
a.description = dom.innerHTML; a.description = dom.innerHTML;
console.log("new DOM:",dom.innerHTML);
this.update_board_artifact_viewmodel(a); this.update_board_artifact_viewmodel(a);
this.queue_artifact_for_save(a); this.queue_artifact_for_save(a);
@@ -2526,11 +2521,18 @@ var SpacedeckSections = {
}, },
show_toolbar_props: function() { show_toolbar_props: function() {
if (this.selection_metrics.count==0) return; if (this.selection_metrics.count==0) {
this.toolbar_lock_in = false;
return;
}
arts = this.selected_artifacts(); arts = this.selected_artifacts();
// check if selected artifacts are all from the same user
let same_user = true;
for (var i=0;i<arts.length; i++) { for (var i=0;i<arts.length; i++) {
if (arts[i].mime=="x-spacedeck/zone") return; if (arts[i].mime=="x-spacedeck/zone") return;
if (arts[i].user_id!==this.user._id) same_user = false;
} }
this.toolbar_lock_in = same_user;
this.toolbar_props_in = true; this.toolbar_props_in = true;
}, },

View File

@@ -6,7 +6,7 @@
function setup_whiteboard_directives() { function setup_whiteboard_directives() {
var mode_touch = false; var mode_touch = false;
if ('ontouchstart' in window) { if ('ontouchstart' in window) {
mode_touch = true; mode_touch = true;
var edown = "touchstart"; var edown = "touchstart";
@@ -38,7 +38,7 @@ function setup_whiteboard_directives() {
$(el).bind("mousedown", this.handle_mouse_down_space.bind(this)); $(el).bind("mousedown", this.handle_mouse_down_space.bind(this));
$(el).bind("mousemove", this.handle_mouse_move.bind(this)); $(el).bind("mousemove", this.handle_mouse_move.bind(this));
$(el).bind("mouseup", this.handle_mouse_up_space.bind(this)); $(el).bind("mouseup", this.handle_mouse_up_space.bind(this));
$(el).bind("wheel", this.handle_wheel_space.bind(this)); $(el).bind("wheel", this.handle_wheel_space.bind(this));
$(document.body).bind("mouseleave", this.handle_mouse_leave.bind(this)); $(document.body).bind("mouseleave", this.handle_mouse_leave.bind(this));
@@ -99,7 +99,7 @@ function setup_whiteboard_directives() {
this.handle_mouse_down_space(evt); this.handle_mouse_down_space(evt);
return; return;
} }
if ($scope.active_tool == "note") { if ($scope.active_tool == "note") {
this.handle_mouse_down_space(evt, true); this.handle_mouse_down_space(evt, true);
return; return;
@@ -154,7 +154,7 @@ function setup_whiteboard_directives() {
var a = $scope.find_artifact_by_id(evt.currentTarget.id.replace("artifact-","")); var a = $scope.find_artifact_by_id(evt.currentTarget.id.replace("artifact-",""));
if (!a) return; if (!a) return;
if (a.payload_uri) { if (a.payload_uri) {
$scope.download_selected_artifacts(); $scope.download_selected_artifacts();
} }
@@ -200,10 +200,10 @@ function setup_whiteboard_directives() {
var $scope = this.vm.$root; var $scope = this.vm.$root;
if (!evt.ctrlKey && !evt.shiftKey) return; if (!evt.ctrlKey && !evt.shiftKey) return;
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
var amount = 1; var amount = 1;
var dy = evt.originalEvent.deltaY; var dy = evt.originalEvent.deltaY;
if (dy>0) { if (dy>0) {
@@ -222,7 +222,7 @@ function setup_whiteboard_directives() {
if (!force && evt.which != 2) { if (!force && evt.which != 2) {
if (evt.target != evt.currentTarget && !_.include(["wrapper"],evt.target.className)) return; if (evt.target != evt.currentTarget && !_.include(["wrapper"],evt.target.className)) return;
} }
var $scope = this.vm.$root; var $scope = this.vm.$root;
$scope.opened_dialog="none"; $scope.opened_dialog="none";
@@ -234,7 +234,7 @@ function setup_whiteboard_directives() {
if ((mode_touch && $scope.active_tool=="pointer") || evt.which == 2 || evt.buttons == 4) { if ((mode_touch && $scope.active_tool=="pointer") || evt.which == 2 || evt.buttons == 4) {
$scope.active_tool = "pan"; $scope.active_tool = "pan";
} }
if ($scope.active_tool=="note") { if ($scope.active_tool=="note") {
this.deselect(); this.deselect();
this.mouse_state = "transform"; this.mouse_state = "transform";
@@ -285,6 +285,7 @@ function setup_whiteboard_directives() {
$scope.start_adding_placeholder(evt); $scope.start_adding_placeholder(evt);
return; return;
} else if ($scope.active_tool=="pan") { } else if ($scope.active_tool=="pan") {
this.deselect();
this.start_pan(evt); this.start_pan(evt);
return; return;
} }
@@ -305,7 +306,7 @@ function setup_whiteboard_directives() {
this.old_panx = el.scrollLeft; this.old_panx = el.scrollLeft;
this.old_pany = el.scrollTop; this.old_pany = el.scrollTop;
} }
var cursor = this.cursor_point_to_space(evt); var cursor = this.cursor_point_to_space(evt);
$scope.mouse_ox = cursor.x; $scope.mouse_ox = cursor.x;
$scope.mouse_oy = cursor.y; $scope.mouse_oy = cursor.y;
@@ -314,7 +315,7 @@ function setup_whiteboard_directives() {
deselect: function() { deselect: function() {
var $scope = this.vm.$root; var $scope = this.vm.$root;
$scope.deselect(); $scope.deselect();
}, },
@@ -342,7 +343,7 @@ function setup_whiteboard_directives() {
rects_intersecting: function(r1,r2) { rects_intersecting: function(r1,r2) {
if (!r1 || !r2) return false; if (!r1 || !r2) return false;
if ( (r1.x+r1.w < r2.x) if ( (r1.x+r1.w < r2.x)
|| (r1.x > r2.x+r2.w) || (r1.x > r2.x+r2.w)
|| (r1.y+r1.h < r2.y) || (r1.y+r1.h < r2.y)
@@ -352,7 +353,7 @@ function setup_whiteboard_directives() {
artifacts_in_rect: function(rect) { artifacts_in_rect: function(rect) {
if (!rect) return []; if (!rect) return [];
var $scope = this.vm.$root; var $scope = this.vm.$root;
return _.filter($scope.active_space_artifacts, function(a) { return _.filter($scope.active_space_artifacts, function(a) {
@@ -688,7 +689,7 @@ function setup_whiteboard_directives() {
var $scope = this.vm.$root; var $scope = this.vm.$root;
evt.preventDefault(); evt.preventDefault();
if (this.mouse_state == "lasso") { if (this.mouse_state == "lasso") {
var lasso_rect = this.abs_rect(this.lasso); var lasso_rect = this.abs_rect(this.lasso);
@@ -696,7 +697,7 @@ function setup_whiteboard_directives() {
var arts = this.artifacts_in_rect(lasso_rect); var arts = this.artifacts_in_rect(lasso_rect);
this.multi_select(arts); this.multi_select(arts);
} else { } else {
if (this._no_artifact_toolbar_this_round) { if (this._no_artifact_toolbar_this_round) {
this._no_artifact_toolbar_this_round = false; this._no_artifact_toolbar_this_round = false;
} else { } else {
@@ -708,7 +709,7 @@ function setup_whiteboard_directives() {
} }
else if (_.include(["transform","move","vector_transform","scribble"],this.mouse_state)) { else if (_.include(["transform","move","vector_transform","scribble"],this.mouse_state)) {
var ars = $scope.selected_artifacts(); var ars = $scope.selected_artifacts();
for (var i=0; i<ars.length; i++) { for (var i=0; i<ars.length; i++) {
if (_.include(["text","placeholder"],$scope.artifact_major_type(ars[i]))) { if (_.include(["text","placeholder"],$scope.artifact_major_type(ars[i]))) {
@@ -723,6 +724,9 @@ function setup_whiteboard_directives() {
//save_artifact(ars[i], null, $scope.display_saving_error); //save_artifact(ars[i], null, $scope.display_saving_error);
} }
// update vector handles
$scope.update_selection_metrics();
} }
if (this.mouse_state == "text_editor") { if (this.mouse_state == "text_editor") {
@@ -794,7 +798,7 @@ function setup_whiteboard_directives() {
$scope.websocket_send(cursor_msg); $scope.websocket_send(cursor_msg);
} }
// side effects ftw! // side effects ftw!
$scope.snap_ruler_x = -1000; $scope.snap_ruler_x = -1000;
$scope.snap_ruler_y = -1000; $scope.snap_ruler_y = -1000;
@@ -818,7 +822,7 @@ function setup_whiteboard_directives() {
if (this.mouse_state == "move") { if (this.mouse_state == "move") {
$scope.hide_toolbar_props(); $scope.hide_toolbar_props();
var snap_dx = 0; var snap_dx = 0;
var snap_dy = 0; var snap_dy = 0;
@@ -878,7 +882,7 @@ function setup_whiteboard_directives() {
} }
$scope.hide_toolbar_props(); $scope.hide_toolbar_props();
var ew = (edges.x2-edges.x1); var ew = (edges.x2-edges.x1);
var eh = (edges.y2-edges.y1); var eh = (edges.y2-edges.y1);
@@ -924,7 +928,7 @@ function setup_whiteboard_directives() {
} else if (this.mouse_state == "vector_transform") { } else if (this.mouse_state == "vector_transform") {
$scope.hide_toolbar_props(); $scope.hide_toolbar_props();
var _this = this; var _this = this;
$scope.update_selected_artifacts(function(a) { $scope.update_selected_artifacts(function(a) {
var old_a = $scope.find_artifact_before_transaction(a); var old_a = $scope.find_artifact_before_transaction(a);
@@ -941,18 +945,14 @@ function setup_whiteboard_directives() {
// special case for arrow's 3rd point // special case for arrow's 3rd point
if (a.shape == "arrow" && $scope.selected_control_point_idx!=2) { if (a.shape == "arrow" && $scope.selected_control_point_idx!=2) {
/*control_points[2].dx += dx/2;
control_points[2].dy += dy/2; */
control_points[2].dx = (control_points[0].dx+control_points[1].dx)/2; control_points[2].dx = (control_points[0].dx+control_points[1].dx)/2;
control_points[2].dy = (control_points[0].dy+control_points[1].dy)/2; control_points[2].dy = (control_points[0].dy+control_points[1].dy)/2;
} }
return _this.normalize_control_points(control_points, old_a); return _this.normalize_control_points(control_points, old_a);
}); }, false, true); // override_locked: false, temporary: true
} else if (this.mouse_state == "scribble") { } else if (this.mouse_state == "scribble") {
$scope.update_selected_artifacts(function(a) { $scope.update_selected_artifacts(function(a) {
var old_a = a; var old_a = a;

View File

@@ -15217,6 +15217,8 @@ button.close {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-size: cover; } background-size: cover; }
.artifact .video.playing video {
z-index: 1; }
.artifact .video .title { .artifact .video .title {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
@@ -15230,13 +15232,15 @@ button.close {
font-size: 10px; } font-size: 10px; }
.artifact .video video { .artifact .video video {
width: 100%; width: 100%;
height: 100%; } height: 100%;
position: absolute; }
.artifact .video .tl-controls { .artifact .video .tl-controls {
position: absolute; position: absolute;
bottom: 10px; top: 10px;
left: 10px; left: 10px;
right: 10px; right: 10px;
text-align: center; } text-align: center;
z-index: 2; }
.artifact .video .tl-controls .btn { .artifact .video .tl-controls .btn {
margin-top: 20px; } margin-top: 20px; }
.artifact .audio { .artifact .audio {

View File

@@ -324,6 +324,12 @@
height: 100%; height: 100%;
background-size: cover; background-size: cover;
&.playing {
video {
z-index: 1;
}
}
.title { .title {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
@@ -340,14 +346,16 @@
video { video {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute;
} }
.tl-controls { .tl-controls {
position: absolute; position: absolute;
bottom: 10px; top: 10px;
left: 10px; left: 10px;
right: 10px; right: 10px;
text-align: center; text-align: center;
z-index: 2;
.btn { .btn {
margin-top: 20px; margin-top: 20px;

View File

@@ -85,13 +85,13 @@
v-bind:class="{text-editing:(editing_artifact_id==a._id && (a.view.major_type=='text' || a.view.major_type=='shape'))}" v-bind:class="{text-editing:(editing_artifact_id==a._id && (a.view.major_type=='text' || a.view.major_type=='shape'))}"
id="artifact-{{a._id}}"> id="artifact-{{a._id}}">
<div v-if="a.view && a.view.major_type" style="height:100%; width:100%" v-bind:title="(a.editor_name || (a.user && a.user.nickname) || '')"> <div v-if="a.view && a.view.major_type" style="height:100%; width:100%" v-bind:title="(a.editor_name || (a.user && a.user.nickname) || '')">
<span v-if="a.locked && is_selected(a)" class="link-wrapper"> <span v-if="a.locked && is_selected(a)" class="link-wrapper">
<span class="btn btn-sm btn-icon btn-round btn-primary"> <span class="btn btn-sm btn-icon btn-round btn-primary">
<span class="icon icon-lock-closed"></span> <span class="icon icon-lock-closed"></span>
</span>
</span> </span>
</span>
<!-- text --> <!-- text -->
<div v-if="a.view.major_type == 'text'" class="text" v-bind:style="a.view.inner_style"> <div v-if="a.view.major_type == 'text'" class="text" v-bind:style="a.view.inner_style">
<div class="text-table"> <div class="text-table">
@@ -151,28 +151,11 @@
</div> </div>
<!-- video --> <!-- video -->
<div v-if="a.view.major_type == 'video'" v-videoplayer="a" class="video" v-bind:style="a.view.inner_style"> <div v-if="a.view.major_type == 'video'" class="video">
<video preload="metadata" v-bind:poster="a.view.thumbnail_uri"> <video preload="metadata" controls="auto" v-bind:poster="a.view.thumbnail_uri">
<source v-for="rep in a.view.payload_alternatives" v-bind:src="rep.payload_uri" v-bind:type="rep.mime" /> <source v-for="rep in a.view.payload_alternatives" v-bind:src="rep.payload_uri" v-bind:type="rep.mime" />
<source v-if="a.view.payload_uri && a.view.mime" v-bind:src="a.view.payload_uri" v-bind:type="a.view.mime" /> <source v-if="a.view.payload_uri && a.view.mime" v-bind:src="a.view.payload_uri" v-bind:type="a.view.mime" />
</video> </video>
<div class="tl-controls">
<div class="btn btn-md btn-toggle btn-round" v-bind:class="{alt:a.player_view.state=='playing'}">
<span class="btn-option play">
<span class="icon icon-controls-play"></span>
</span>
<span class="btn-option pause">
<span class="icon icon-controls-pause"></span>
</span>
</div>
<span class="btn btn-md btn-round btn-icon stop" v-show="a.player_view.state=='playing' || a.player_view.state=='paused'">
<span class="icon icon-controls-stop"></span>
</span>
</div>
<div class="spinner"></div> <div class="spinner"></div>
<div class="progress" v-bind:style="{width: a.view.progress+'%'}">{{a.description}}</div> <div class="progress" v-bind:style="{width: a.view.progress+'%'}">{{a.description}}</div>
</div> </div>

View File

@@ -4,7 +4,7 @@
<div class="dialog-section"> <div class="dialog-section">
<label class="btn btn-xxl btn-transparent btn-icon"> <label class="btn btn-xxl btn-transparent btn-icon">
<span class="icon icon-picture-upload"></span> <span class="icon icon-picture-upload"></span>
<input type="file" accept="*/*" multiple v-on:change="handle_image_file_upload($event)" id="image_file_upload"> <input type="file" multiple v-on:change="handle_image_file_upload($event)" id="image_file_upload">
</label> </label>
<p>Click to Upload<br/> or drag file(s) anywhere.</p> <p>Click to Upload<br/> or drag file(s) anywhere.</p>
</div> </div>

View File

@@ -7,12 +7,12 @@
<button class="btn btn-divider"></button> <button class="btn btn-divider"></button>
<button class="btn btn-transparent btn-icon-labeled" v-on:click="lock_selected_artifacts()" v-if="active_space_role=='admin'" title="<%=__("lock")%>"> <button class="btn btn-transparent btn-icon-labeled" v-on:click="lock_selected_artifacts()" v-if="active_space_role=='admin' || toolbar_lock_in" title="<%=__("lock")%>">
<span class="icon icon-lock-closed"></span> <span class="icon icon-lock-closed"></span>
<span class="icon-label"><%=__("lock")%></span> <span class="icon-label"><%=__("lock")%></span>
</button> </button>
<button class="btn btn-transparent btn-icon-labeled" v-on:click="unlock_selected_artifacts()" v-if="active_space_role=='admin'" title="<%=__("unlock")%>"> <button class="btn btn-transparent btn-icon-labeled" v-on:click="unlock_selected_artifacts()" v-if="active_space_role=='admin' || toolbar_lock_in" title="<%=__("unlock")%>">
<span class="icon icon-lock-open"></span> <span class="icon icon-lock-open"></span>
<span class="icon-label"><%=__("unlock")%></span> <span class="icon-label"><%=__("unlock")%></span>
</button> </button>

View File

@@ -1,18 +1,18 @@
<div class="toolbar toolbar-elements" v-bind:class="{in:toolbar_artifacts_in,out:!toolbar_artifacts_in}" v-show="!is_active_space_role('viewer') && active_space_loaded"> <div class="toolbar toolbar-elements" v-bind:class="{in:toolbar_artifacts_in,out:!toolbar_artifacts_in}" v-show="!is_active_space_role('viewer') && active_space_loaded">
<div class="btn-group light vertical"> <div class="btn-group light vertical">
<a class="btn btn-icon btn-transparent" <a class="btn btn-icon btn-transparent"
title="<%=__("home")%>" href="/spaces" title="<%=__("home")%>" href="/spaces"
v-if="(!active_space.parent_space_id && !guest_nickname && !embedded)"> v-if="(!active_space.parent_space_id && !guest_nickname && !embedded)">
<span class="icon icon-folder"></span> <span class="icon icon-folder"></span>
</a> </a>
<a class="btn btn-icon btn-dark" <a class="btn btn-icon btn-dark"
title="Parent Folder" title="Parent Folder"
href="/folders/{{active_space.parent_space_id}}" href="/folders/{{active_space.parent_space_id}}"
v-if="(active_space.parent_space_id && !guest_nickname && !embedded)"> v-if="(active_space.parent_space_id && !guest_nickname && !embedded)">
<span class="icon icon-sd6 icon-svg"></span> <span class="icon icon-sd6 icon-svg"></span>
</a> </a>
@@ -35,15 +35,16 @@
<span class="icon icon-tool-scribble"></span> <span class="icon icon-tool-scribble"></span>
<span class="icon-label"><%=__("tool_scribble")%></span> <span class="icon-label"><%=__("tool_scribble")%></span>
</button> </button>
<button class="btn btn-icon-labeled btn-transparent" v-on:click="start_drawing_arrow()" v-bind:class="{active:active_tool=='arrow'}" title="<%=__("tool_arrow")%>"> <button class="btn btn-icon-labeled btn-transparent" v-on:click="start_drawing_arrow()" v-bind:class="{active:active_tool=='arrow'}" title="<%=__("tool_arrow")%>">
<span class="icon icon-tool-arrow"></span> <span class="icon icon-tool-arrow"></span>
<span class="icon-label"><%=__("tool_arrow")%></span> <span class="icon-label"><%=__("tool_arrow")%></span>
</button> </button>
<div class="dropdown bottom light center"> <div class="dropdown bottom light center">
<div class="btn-collapse in"> <div class="btn-collapse in">
<button class="btn btn-transparent btn-icon-labeled" v-on:click="handle_insert_image_url()" v-on:touchstart="handle_insert_image_url()" title="<%=__("media")%>"> <input type="file" multiple v-on:change="handle_image_file_upload($event)" id="image_file_upload" class="btn btn-transparent btn-icon-labeled" style="position: absolute; z-index: 1; opacity: 0;">
<button class="btn btn-transparent btn-icon-labeled" title="<%=__("media")%>">
<span class="icon icon-upload"></span> <span class="icon icon-upload"></span>
<span class="icon-label" ><%=__("media")%></span> <span class="icon-label" ><%=__("media")%></span>
</button> </button>
@@ -59,19 +60,6 @@
</div> </div>
</div> </div>
<div class="dropdown top left light">
<div class="btn-collapse">
<button class="btn btn-transparent btn-icon-labeled" v-bind:class="{open:opened_dialog=='image'}" v-on:click="open_dialog('image')" title="<%=__("image")%>">
<span class="icon icon-picture"></span>
<span class="icon-label"><%=__("image")%></span>
</button>
</div>
<div class="dialog">
<%- include("./image.html") %>
</div>
</div>
<div class="dropdown top left light" v-bind:class="{open:opened_dialog=='zones'}"> <div class="dropdown top left light" v-bind:class="{open:opened_dialog=='zones'}">
<div class="btn-collapse in"> <div class="btn-collapse in">
<button class="btn btn-transparent btn-icon-labeled" v-bind:class="{open:opened_dialog=='zones'}" v-on:click="open_dialog('zones')" title="<%=__("tool_zones")%>"> <button class="btn btn-transparent btn-icon-labeled" v-bind:class="{open:opened_dialog=='zones'}" v-on:click="open_dialog('zones')" title="<%=__("tool_zones")%>">
@@ -84,7 +72,7 @@
<%- include("./zones.html") %> <%- include("./zones.html") %>
</div> </div>
</div> </div>
<button class="btn btn-divider" v-show="logged_in"></button> <button class="btn btn-divider" v-show="logged_in"></button>
<div class="dropdown top left center" v-show="logged_in" v-bind:class="{open:opened_dialog=='background'}"> <div class="dropdown top left center" v-show="logged_in" v-bind:class="{open:opened_dialog=='background'}">
@@ -107,8 +95,8 @@
<span class="icon icon-share"></span> <span class="icon icon-share"></span>
<span class="icon-label"><%= __('share') %></span> <span class="icon-label"><%= __('share') %></span>
</button> </button>
<!-- <!--
<li v-on:click="edit_space_title()" v-if="logged_in"> <li v-on:click="edit_space_title()" v-if="logged_in">
<span> <span>
<span class="icon icon-sm icon-tag"></span> <span class="icon icon-sm icon-tag"></span>

View File

@@ -40,7 +40,7 @@
<button class="btn btn-divider"></button> <button class="btn btn-divider"></button>
--> -->
<div class="dropdown top light right" v-bind:class="{open:opened_dialog=='text-styles'}"> <div class="dropdown top light right" v-bind:class="{open:opened_dialog=='text-styles'}">
<div class="btn-collapse in"> <div class="btn-collapse in">
<button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('text-styles')" v-bind:class="{open : opened_dialog=='text-styles'}" title="<%=__("tool_styles")%>"> <button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('text-styles')" v-bind:class="{open : opened_dialog=='text-styles'}" title="<%=__("tool_styles")%>">
@@ -53,7 +53,7 @@
<%- include("./text-styles.html") %> <%- include("./text-styles.html") %>
</div> </div>
</div> </div>
<div class="dropdown top light right" v-bind:class="{open:opened_dialog=='type-align'}"> <div class="dropdown top light right" v-bind:class="{open:opened_dialog=='type-align'}">
<div class="btn-collapse" v-bind:class="{in:selection_metrics.contains_text}"> <div class="btn-collapse" v-bind:class="{in:selection_metrics.contains_text}">
<button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('type-align')" v-bind:class="{open : opened_dialog=='type-align'}" title="<%=__("tool_align")%>"> <button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('type-align')" v-bind:class="{open : opened_dialog=='type-align'}" title="<%=__("tool_align")%>">
@@ -80,9 +80,9 @@
<%- include("./layout.html") %> <%- include("./layout.html") %>
</div> </div>
</div> </div>
<div class="dropdown top light right" v-bind:class="{open:opened_dialog=='text-settings'}"> <div class="dropdown top light right" v-bind:class="{open:opened_dialog=='text-settings'}">
<div class="btn-collapse in"> <div class="btn-collapse in">
<button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('text-settings')" v-bind:class="{open : opened_dialog=='text-settings'}" title="<%=__("tool_font")%>"> <button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('text-settings')" v-bind:class="{open : opened_dialog=='text-settings'}" title="<%=__("tool_font")%>">
<span class="icon icon-text-typeface"></span> <span class="icon icon-text-typeface"></span>
@@ -97,6 +97,17 @@
<button class="btn btn-divider"></button> <button class="btn btn-divider"></button>
<div class="dropdown bottom light center">
<div class="btn-collapse" v-bind:class="{in:selection_metrics.contains_text}">
<button
class="btn btn-icon-labeled btn-transparent"
v-on:click="delayed_edit_artifact()">
<span class="icon icon-pencil"></span>
<span class="icon-label"><%=__("tool_edit_text")%></span>
</button>
</div>
</div>
<div class="dropdown top light right" v-bind:class="{open:opened_dialog=='object-options'}"> <div class="dropdown top light right" v-bind:class="{open:opened_dialog=='object-options'}">
<button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('object-options')" v-bind:class="{open : opened_dialog=='object-options'}"> <button class="btn btn-transparent btn-icon-labeled" v-on:click="open_dialog('object-options')" v-bind:class="{open : opened_dialog=='object-options'}">
<span class="icon icon-cogwheel"></span> <span class="icon icon-cogwheel"></span>
@@ -107,6 +118,6 @@
<%- include("./object-options.html") %> <%- include("./object-options.html") %>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -7,15 +7,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link href="/images/favicon.png" rel="icon" type="image/x-icon" /> <link href="/images/favicon.png" rel="icon" type="image/x-icon" />
<link href='https://fonts.googleapis.com/css?family=Inter' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/stylesheets/style.css"> <link rel="stylesheet" href="/stylesheets/style.css">
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script> <script>
//window.browser_lang = '< %= locale %>';
var ENV = { var ENV = {
name: 'development', name: 'development',
webHost: location.host, webHost: location.host,
@@ -59,7 +55,7 @@
<script src="/javascripts/spacedeck_whiteboard.js"></script> <script src="/javascripts/spacedeck_whiteboard.js"></script>
<script src="/javascripts/spacedeck_directives.js"></script> <script src="/javascripts/spacedeck_directives.js"></script>
<script src="/javascripts/spacedeck_vue.js"></script> <script src="/javascripts/spacedeck_vue.js"></script>
<script>if (window.module) module = window.module;</script> <script>if (window.module) module = window.module;</script>
</head> </head>
@@ -86,6 +82,6 @@
window.locales.de.translation = <%- include("./../locales/de.js") %>; window.locales.de.translation = <%- include("./../locales/de.js") %>;
window.locales.fr.translation = <%- include("./../locales/fr.js") %>; window.locales.fr.translation = <%- include("./../locales/fr.js") %>;
window.locales.oc.translation = <%- include("./../locales/oc.js") %>; window.locales.oc.translation = <%- include("./../locales/oc.js") %>;
window.locales.es.translation = <%- include("./../locales/es.js") %>; window.locales.es.translation = <%- include("./../locales/es.js") %>;
</script> </script>
</html> </html>