2017-04-07 01:29:05 +02:00
|
|
|
|
/*
|
|
|
|
|
SpacedeckSpaces
|
|
|
|
|
This module contains functions dealing with Spaces UI.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var SpacedeckSpaces = {
|
|
|
|
|
|
|
|
|
|
data: {
|
|
|
|
|
active_space: {advanced:{}},
|
|
|
|
|
active_space_loaded: false,
|
|
|
|
|
active_space_role: "viewer",
|
|
|
|
|
active_space_version_dirty: true,
|
|
|
|
|
active_space_messages: [],
|
|
|
|
|
active_space_memberships: [],
|
|
|
|
|
active_folder_history_items: [],
|
|
|
|
|
active_space_users: [],
|
|
|
|
|
active_space_artifacts: [],
|
|
|
|
|
active_space_path: [],
|
|
|
|
|
access_settings_space: null,
|
|
|
|
|
access_settings_memberships: [],
|
|
|
|
|
duplicate_folders: [],
|
|
|
|
|
duplicate_folder_id: "",
|
|
|
|
|
pending_pdf_files: [],
|
|
|
|
|
|
|
|
|
|
meta_visible: false,
|
|
|
|
|
meta_unseen: 0,
|
|
|
|
|
|
|
|
|
|
present_mode: false,
|
|
|
|
|
space_editing_title: false,
|
|
|
|
|
create_space_title: "",
|
|
|
|
|
folder_reverse: 1,
|
|
|
|
|
embedded: false,
|
|
|
|
|
remix_cta: "Create Reply",
|
|
|
|
|
publish_cta: "Publish",
|
|
|
|
|
remix_copying: true,
|
|
|
|
|
remix_style: "",
|
|
|
|
|
guest_signup_enabled: false,
|
|
|
|
|
space_embed_html: "",
|
|
|
|
|
share_base: location.origin,
|
|
|
|
|
share_base_url: location.origin+"/spaces/",
|
|
|
|
|
share_base_url_enc: encodeURIComponent(location.origin+"/spaces/"),
|
|
|
|
|
social_bar: true,
|
|
|
|
|
can_add_comment: false,
|
|
|
|
|
|
|
|
|
|
space_info_section: "access",
|
|
|
|
|
editors_section: "list",
|
|
|
|
|
selected_member: null,
|
|
|
|
|
invite_member_role: 'viewer',
|
|
|
|
|
invite_email_error: null,
|
|
|
|
|
invite_email: "",
|
|
|
|
|
invite_message: "",
|
|
|
|
|
active_join_link: "",
|
|
|
|
|
join_link_role: "viewer",
|
|
|
|
|
|
|
|
|
|
mouse_state: "idle",
|
|
|
|
|
|
|
|
|
|
// folders
|
|
|
|
|
active_folder: null,
|
|
|
|
|
folder_sorting: "updated_at",
|
|
|
|
|
|
|
|
|
|
folder_spaces_filter: null,
|
|
|
|
|
active_path_length : 0,
|
|
|
|
|
|
|
|
|
|
space_comment: "",
|
|
|
|
|
folder_spaces_search: "",
|
|
|
|
|
|
|
|
|
|
// map of artifact IDs to medium rich text editor objects
|
|
|
|
|
medium_for_object: {},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
search_spaces: function() {
|
|
|
|
|
var query = this.folder_spaces_search;
|
|
|
|
|
load_spaces_search(query, function(spaces) {
|
|
|
|
|
this.active_profile_spaces = spaces;
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
guest_logout: function() {
|
|
|
|
|
if ("localStorage" in window && localStorage) {
|
|
|
|
|
delete localStorage['guest_nickname'];
|
|
|
|
|
}
|
|
|
|
|
this.guest_nickname = "";
|
|
|
|
|
location.reload();
|
|
|
|
|
},
|
|
|
|
|
ask_guestname: function(dft, cb) {
|
2018-05-07 20:00:02 +02:00
|
|
|
|
smoke.prompt(__('what_is_your_name', "Spacedeck") , function(content) {
|
2017-04-07 01:29:05 +02:00
|
|
|
|
if (!content || (content.length === 0)) {
|
|
|
|
|
this.ask_guestname(dft, cb);
|
|
|
|
|
} else {
|
|
|
|
|
this.guest_nickname = content;
|
|
|
|
|
|
|
|
|
|
if ("localStorage" in window && localStorage) {
|
|
|
|
|
try {
|
|
|
|
|
localStorage['guest_nickname'] = this.guest_nickname;
|
2018-05-07 20:00:02 +02:00
|
|
|
|
} catch(e) {
|
2017-04-07 01:29:05 +02:00
|
|
|
|
console.error(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (cb) cb();
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), {value: dft || "Guest "+parseInt(10000*Math.random()), ok: __("ok"), cancel: __("cancel")});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
load_space: function(space_id, on_success, on_error) {
|
|
|
|
|
|
|
|
|
|
console.log("load space: ", space_id);
|
|
|
|
|
this.folder_spaces_filter="";
|
|
|
|
|
this.folder_spaces_search="";
|
|
|
|
|
|
|
|
|
|
space_auth = get_query_param("spaceAuth");
|
|
|
|
|
|
|
|
|
|
var userReady = function() {
|
|
|
|
|
if (get_query_param("embedded")) {
|
|
|
|
|
this.embedded = true;
|
|
|
|
|
this.guest_signup_enabled = true;
|
|
|
|
|
if (get_query_param("publish_cta")) {
|
|
|
|
|
this.publish_cta = get_query_param("publish_cta");
|
|
|
|
|
}
|
|
|
|
|
if (get_query_param("nosocial")) {
|
|
|
|
|
this.social_bar = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (get_query_param("confirm") && this.logged_in) {
|
|
|
|
|
var token = get_query_param("confirm");
|
|
|
|
|
confirm_user(this.user, token, function() {
|
|
|
|
|
this.redirect_to("/spaces/"+space_id+"?show_access=1");
|
|
|
|
|
}.bind(this), function() {
|
|
|
|
|
alert("An error occured confirming your email with the given token.");
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.close_dropdown();
|
|
|
|
|
|
|
|
|
|
this.active_space_loaded = false;
|
|
|
|
|
this.viewport_zoom = 1;
|
|
|
|
|
this.viewport_zoom_percent = 100;
|
|
|
|
|
|
|
|
|
|
this.loading_space_id = space_id;
|
|
|
|
|
this.present_mode = false;
|
|
|
|
|
this.active_space_is_readonly = true;
|
|
|
|
|
this.opened_dialog = "none";
|
|
|
|
|
this.open_space_dialog = "none";
|
|
|
|
|
|
|
|
|
|
this.selected_artifacts_dict = {};
|
|
|
|
|
this.update_selection_metrics();
|
|
|
|
|
|
|
|
|
|
this.can_add_comment = false;
|
|
|
|
|
|
|
|
|
|
var is_home = false;
|
|
|
|
|
if (this.user) {
|
|
|
|
|
is_home = (space_id == this.user.home_folder_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.title = "Loading… | Spacedeck";
|
|
|
|
|
|
|
|
|
|
load_space(space_id, function(space, role) {
|
|
|
|
|
document.title = space.name;
|
|
|
|
|
|
|
|
|
|
this.active_space_role = role || "viewer"; //via req header from backend
|
|
|
|
|
|
|
|
|
|
this.space_embed_html = "<iframe width=\"1024\" height=\"768\" seamless src=\""+ENV.webEndpoint+"/spaces/"+space._id+"?embedded=1\"></iframe>";
|
|
|
|
|
|
|
|
|
|
if (!is_home) {
|
|
|
|
|
load_members(space, function(members) {
|
|
|
|
|
this.active_space_memberships = members;
|
|
|
|
|
}.bind(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log("[websocket] auth start");
|
|
|
|
|
|
|
|
|
|
if (space.space_type == "folder") {
|
|
|
|
|
this.active_space = {advanced:{}};
|
|
|
|
|
document.title = "Spacedeck";
|
|
|
|
|
|
|
|
|
|
load_spaces(space_id, is_home, function(spaces) {
|
|
|
|
|
space.children = spaces;
|
|
|
|
|
|
|
|
|
|
this.loading_space_id = null;
|
|
|
|
|
this.active_profile_spaces = space.children;
|
|
|
|
|
this.active_folder = space;
|
|
|
|
|
this.access_settings_space = space;
|
|
|
|
|
|
|
|
|
|
this.auth_websocket(this.active_folder);
|
|
|
|
|
|
|
|
|
|
this.load_space_path(this.active_folder);
|
|
|
|
|
|
|
|
|
|
if (is_home) {
|
|
|
|
|
this.root_folder = space;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
load_history(space, function(history) {
|
|
|
|
|
console.log("loaded digest", history);
|
|
|
|
|
this.active_folder_history_items = history;
|
|
|
|
|
this.meta_unseen = 0;
|
|
|
|
|
|
|
|
|
|
if ("localStorage" in window && localStorage) {
|
|
|
|
|
var last_seen = parseInt(localStorage[this.meta_last_seen_key()], 10);
|
|
|
|
|
} else {
|
|
|
|
|
var last_seen = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var i=0; i<history.length; i++) {
|
|
|
|
|
var item = history[i];
|
|
|
|
|
var t = new Date(item.last_action).getTime();
|
|
|
|
|
var my_own = false;
|
|
|
|
|
if (item.users.length==1 && item.users[0]=="you") {
|
|
|
|
|
my_own = true;
|
|
|
|
|
}
|
|
|
|
|
if (t>last_seen && !my_own) this.meta_unseen++;
|
|
|
|
|
}
|
|
|
|
|
}.bind(this));
|
|
|
|
|
|
|
|
|
|
this.active_view = "folders";
|
|
|
|
|
}.bind(this));
|
|
|
|
|
|
|
|
|
|
if ("localStorage" in window) {
|
|
|
|
|
var key = "folder_sorting_"+space_id;
|
|
|
|
|
var key2 = "folder_reverse_"+space_id;
|
|
|
|
|
if (localStorage[key] && localStorage[key2]) {
|
|
|
|
|
this.folder_sorting = localStorage[key];
|
|
|
|
|
this.folder_reverse = parseInt(localStorage[key2]);
|
|
|
|
|
console.log("loaded folder sorting: ",this.folder_sorting,this.folder_reverse);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// legacy fix
|
|
|
|
|
if (this.folder_sorting == "opened_at") {
|
|
|
|
|
this.folder_sorting = "name";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (space.space_type == "space") {
|
|
|
|
|
this.artifacts = [];
|
|
|
|
|
|
|
|
|
|
this.loading_space_id = null;
|
|
|
|
|
|
|
|
|
|
document.title = space.name;
|
|
|
|
|
|
|
|
|
|
if (space_auth || this.logged_in) {
|
|
|
|
|
this.can_add_comment = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.setup_watches();
|
|
|
|
|
|
|
|
|
|
load_artifacts(space._id, function(artifacts) {
|
|
|
|
|
|
|
|
|
|
// FIXME: how to cleanly handle this error?
|
|
|
|
|
if (!artifacts) {
|
|
|
|
|
artifacts = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: remove kludge
|
|
|
|
|
for (var i=0; i<artifacts.length; i++) {
|
|
|
|
|
this.update_board_artifact_viewmodel(artifacts[i]);
|
|
|
|
|
}
|
|
|
|
|
this.active_space_artifacts = artifacts;
|
|
|
|
|
|
|
|
|
|
this.$set("active_space", space);
|
|
|
|
|
this.active_space = space;
|
|
|
|
|
|
|
|
|
|
this.auth_websocket(this.active_space);
|
|
|
|
|
|
|
|
|
|
this.active_view = "space";
|
|
|
|
|
this.fixup_space_size();
|
|
|
|
|
|
|
|
|
|
if (space._id != this.active_space._id) {
|
|
|
|
|
this.present_mode = true;
|
|
|
|
|
this.active_space_is_readonly = true;
|
|
|
|
|
} else {
|
|
|
|
|
this.active_space_is_readonly = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.discover_zones();
|
|
|
|
|
|
2018-04-12 18:40:58 +02:00
|
|
|
|
//window.setTimeout(function() {
|
|
|
|
|
// this.zoom_to_fit();
|
|
|
|
|
//}.bind(this),10);
|
2017-04-07 01:29:05 +02:00
|
|
|
|
|
|
|
|
|
if (on_success) {
|
|
|
|
|
on_success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.active_space_loaded = true;
|
|
|
|
|
this.extract_properties_from_selection(); // populates zones etc
|
|
|
|
|
|
|
|
|
|
load_comments(space._id, function(messages) {
|
|
|
|
|
if (!messages) messages = [];
|
|
|
|
|
|
|
|
|
|
this.active_space_messages = messages;
|
|
|
|
|
this.refresh_space_comments();
|
|
|
|
|
}.bind(this), function(xhr) { console.error(xhr); });
|
|
|
|
|
|
|
|
|
|
}.bind(this));
|
|
|
|
|
|
|
|
|
|
if (this.active_space_role == "editor" || this.active_space_role == "admin") {
|
|
|
|
|
this.present_mode = false;
|
|
|
|
|
this.active_space_is_readonly = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME
|
|
|
|
|
this.active_join_link = "";
|
|
|
|
|
this.join_link_role = "viewer";
|
|
|
|
|
|
|
|
|
|
// FIXME
|
|
|
|
|
if (this.active_space_role == "admin") {
|
|
|
|
|
this.space_info_section="access";
|
|
|
|
|
} else if (this.active_space_role == "editor") {
|
|
|
|
|
//this.space_info_section="versions";
|
|
|
|
|
} else {
|
|
|
|
|
this.space_info_section="info";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
|
|
|
|
|
if (on_error) {
|
|
|
|
|
return on_error(xhr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (xhr.status == 403) {
|
|
|
|
|
if (!this.logged_in) {
|
|
|
|
|
this.redirect_to("/login?space_id="+space_id);
|
|
|
|
|
} else {
|
|
|
|
|
this.redirect_to("/");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.redirect_to("/not_found");
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this));
|
|
|
|
|
|
|
|
|
|
}.bind(this);
|
|
|
|
|
|
|
|
|
|
var default_guest = "";
|
|
|
|
|
if (("localStorage" in window && localStorage) && localStorage['guest_nickname']) {
|
|
|
|
|
this.guest_nickname = localStorage['guest_nickname'];
|
|
|
|
|
default_guest = this.guest_nickname;
|
|
|
|
|
userReady();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (space_auth) {
|
|
|
|
|
if (this.guest_nickname) {
|
|
|
|
|
userReady();
|
|
|
|
|
} else {
|
|
|
|
|
this.ask_guestname(default_guest, function() {
|
|
|
|
|
userReady();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.guest_nickname = "";
|
|
|
|
|
userReady();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
refresh_space_comments: function() {
|
|
|
|
|
this.meta_unseen = 0;
|
|
|
|
|
var messages = this.active_space_messages;
|
|
|
|
|
var last_seen = 0;
|
|
|
|
|
|
|
|
|
|
if ("localStorage" in window && localStorage) {
|
|
|
|
|
last_seen = parseInt(localStorage[this.meta_last_seen_key()], 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var i=0; i<messages.length; i++) {
|
|
|
|
|
var item = messages[i];
|
|
|
|
|
var t = new Date(item.updated_at).getTime();
|
|
|
|
|
var my_own = false;
|
|
|
|
|
if (this.user && this.user._id!=item.user_id && !item.editor_name) {
|
|
|
|
|
my_own = true;
|
|
|
|
|
}
|
|
|
|
|
if (t>last_seen && !my_own) this.meta_unseen++;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
go_to_next_space: function() {
|
|
|
|
|
var space_ids = this.active_folder.children.map(function(s){return s._id});
|
|
|
|
|
var idx = space_ids.indexOf(this.active_space._id);
|
|
|
|
|
console.log("index: ",idx);
|
|
|
|
|
|
|
|
|
|
var cur_idx = idx;
|
|
|
|
|
var done = false;
|
|
|
|
|
while (!done) {
|
|
|
|
|
var next = this.active_folder.children[(idx+1)%space_ids.length];
|
|
|
|
|
if (next.space_type == "folder") {
|
|
|
|
|
done = false;
|
|
|
|
|
idx++;
|
|
|
|
|
} else {
|
|
|
|
|
done = true;
|
|
|
|
|
}
|
|
|
|
|
if (cur_idx == idx) done = true; // wraparound
|
|
|
|
|
}
|
|
|
|
|
this.load_space(next._id);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
go_to_previous_space: function() {
|
|
|
|
|
var space_ids = this.active_folder.children.map(function(s){return s._id});
|
|
|
|
|
var idx = space_ids.indexOf(this.active_space._id);
|
|
|
|
|
console.log("index: ",idx);
|
|
|
|
|
|
|
|
|
|
var cur_idx = idx;
|
|
|
|
|
var done = false;
|
|
|
|
|
while (!done) {
|
|
|
|
|
var idx = (idx<1?space_ids.length:idx)-1;
|
|
|
|
|
var prev = this.active_folder.children[idx];
|
|
|
|
|
if (prev.space_type == "folder") {
|
|
|
|
|
done = false;
|
|
|
|
|
idx--;
|
|
|
|
|
} else {
|
|
|
|
|
done = true;
|
|
|
|
|
}
|
|
|
|
|
if (cur_idx == idx) done = true; // wraparound
|
|
|
|
|
}
|
|
|
|
|
this.load_space(prev._id);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filtered_folder_children: function(type){
|
|
|
|
|
var type = type ||Â "space";
|
|
|
|
|
return _.filter(this.active_folder.children, function(s){
|
|
|
|
|
return s.space_type == type;
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
load_space_path: function(space) {
|
|
|
|
|
if (!space) return [];
|
|
|
|
|
|
|
|
|
|
load_space_path(space._id, function(path) {
|
|
|
|
|
this.active_space_path = path;
|
|
|
|
|
}.bind(this), function() { console.log("could not load folder path")});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
is_active_space_role: function(rolename) {
|
|
|
|
|
if(!this.active_space) return false;
|
|
|
|
|
return this.active_space_role == rolename;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
create_space: function(space_type) {
|
|
|
|
|
if (!this.active_folder) return;
|
|
|
|
|
|
|
|
|
|
this.close_modal();
|
|
|
|
|
this.folder_spaces_filter="";
|
|
|
|
|
|
|
|
|
|
if (!this.active_folder.children) {
|
|
|
|
|
this.active_folder.children = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!space_type) space_type = "space";
|
|
|
|
|
|
|
|
|
|
var s = {
|
|
|
|
|
name: space_type == "space" ? __("untitled_space") : __("untitled_folder") ,
|
|
|
|
|
artifacts: [],
|
|
|
|
|
space_type: space_type,
|
|
|
|
|
parent_space_id: this.active_folder._id
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (this.create_space_title.length) {
|
|
|
|
|
s.name = this.create_space_title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
save_space(s, function(saved_space) {
|
|
|
|
|
this.active_folder.children.push(saved_space);
|
|
|
|
|
if (space_type != "folder") {
|
|
|
|
|
this.redirect_to("/"+saved_space.space_type+"s/"+saved_space._id, function(succ) {
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.rename_folder(saved_space);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
alert("Error: Could not create Space ("+xhr.status+").");
|
|
|
|
|
}.bind(this));
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space: function(s)Â {
|
|
|
|
|
save_space(s);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
create_space_version: function() {
|
|
|
|
|
|
|
|
|
|
if (!this.is_pro(this.user)) {
|
|
|
|
|
// pro feature
|
|
|
|
|
smoke.confirm(__("spacedeck_pro_ad_versions"), function(confirmed) {
|
|
|
|
|
if (confirmed) this.show_upgrade_modal();
|
|
|
|
|
}.bind(this));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.version_saving = true;
|
|
|
|
|
this.present_mode = false;
|
|
|
|
|
|
|
|
|
|
var s = this.active_space.draft_space;
|
|
|
|
|
console.log("create_space_version:", s);
|
|
|
|
|
|
|
|
|
|
duplicate_space(s, null, function(new_version_space) {
|
|
|
|
|
load_spaces(this.active_space._id, false, function(space) {
|
|
|
|
|
this.version_saving = false;
|
|
|
|
|
this.activate_space_version(space, space.draft_space);
|
|
|
|
|
|
|
|
|
|
alert("Version saved.");
|
|
|
|
|
}.bind(this));
|
|
|
|
|
}.bind(this), function(xhr){
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
finalize_folder_profile_edit: function() {
|
|
|
|
|
save_space(this.active_folder, function(saved_space) {
|
|
|
|
|
this.close_modal();
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
finalize_space_profile_edit: function() {
|
|
|
|
|
save_space(this.active_space, function(saved_space) {
|
|
|
|
|
this.close_modal();
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
delete_space: function(space) {
|
|
|
|
|
smoke.confirm("Really delete "+space.name+"?", function(confirmed) {
|
|
|
|
|
if (!confirmed) return;
|
|
|
|
|
var idx = this.active_folder.children.indexOf(space);
|
|
|
|
|
|
|
|
|
|
delete_space(space, function() {
|
|
|
|
|
if (space.parent_space_id){
|
|
|
|
|
this.redirect_to("/folders/"+space.parent_space_id, function(succ) {});
|
|
|
|
|
} else {
|
|
|
|
|
this.redirect_to("/spaces", function(succ) {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.close_modal();
|
|
|
|
|
|
|
|
|
|
this.active_folder.children.splice(idx,1);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
duplicate_space: function(space) {
|
|
|
|
|
duplicate_space(space, null, function(new_space) {
|
|
|
|
|
//alert("Space duplicated.");
|
|
|
|
|
this.active_folder.children.push(new_space);
|
|
|
|
|
}.bind(this), function(xhr){
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
remove_avatar: function(space) {
|
|
|
|
|
remove_avatar_file("space", space, function(s) {
|
|
|
|
|
this.active_space = s;
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
rename_space: function(space) {
|
|
|
|
|
this.close_dropdown();
|
|
|
|
|
if (space.space_type == "folder") return this.rename_folder(space);
|
|
|
|
|
smoke.prompt(__("new_space_title"), function(title) {
|
|
|
|
|
if (title && title.length) {
|
|
|
|
|
space.name = title;
|
|
|
|
|
save_space(space);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), {value: space.name});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
rename_folder: function(folder) {
|
|
|
|
|
this.close_dropdown();
|
|
|
|
|
|
|
|
|
|
smoke.prompt(__("new_folder_title"), function(title) {
|
|
|
|
|
if (title && title.length) {
|
|
|
|
|
folder.name = title;
|
|
|
|
|
save_space(folder);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), {value: folder.name});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
edit_space_title: function() {
|
|
|
|
|
this.close_dropdown();
|
|
|
|
|
if (this.active_space_role=="editor" || this.active_space_role=="admin") {
|
|
|
|
|
this.space_editing_title = true;
|
|
|
|
|
$("#space-title").focus();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space_title: function(name) {
|
|
|
|
|
this.active_space.name = name;
|
|
|
|
|
save_space(this.active_space, function() {
|
|
|
|
|
this.space_editing_title = false;
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space_keydown: function($event) {
|
|
|
|
|
if ($event) {
|
|
|
|
|
if ($event.keyCode != 13) {
|
|
|
|
|
this.space_editing_title = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$event.preventDefault();
|
|
|
|
|
$event.stopPropagation();
|
|
|
|
|
$event.target.blur();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
save_space(this.active_space, function(updated_space) {
|
|
|
|
|
this.active_space.edit_slug = updated_space.edit_slug;
|
|
|
|
|
this.space_editing_title = false;
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space_description: function($event) {
|
|
|
|
|
$event.preventDefault();
|
|
|
|
|
$event.stopPropagation();
|
|
|
|
|
|
|
|
|
|
var val = $event.target.innerText;
|
|
|
|
|
$event.target.blur();
|
|
|
|
|
this.active_space.description = val;
|
|
|
|
|
save_space(this.active_space);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space_domain: function($event) {
|
|
|
|
|
$event.preventDefault();
|
|
|
|
|
$event.stopPropagation();
|
|
|
|
|
|
|
|
|
|
var val = $event.target.innerText;
|
|
|
|
|
$event.target.blur();
|
|
|
|
|
this.active_space.domain = val;
|
|
|
|
|
save_space(this.active_space);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
download_space: function() {
|
|
|
|
|
smoke.quiz(__("download_space"), function(e, test) {
|
2018-04-12 18:40:58 +02:00
|
|
|
|
if (e == "PDF") {
|
2017-04-07 01:29:05 +02:00
|
|
|
|
this.download_space_as_pdf(this.active_space);
|
2018-04-12 18:40:58 +02:00
|
|
|
|
} else if (e == "ZIP") {
|
2017-04-07 01:29:05 +02:00
|
|
|
|
this.download_space_as_zip(this.active_space);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), {
|
|
|
|
|
button_1: "PDF",
|
|
|
|
|
button_2: "ZIP",
|
|
|
|
|
button_cancel:__("cancel")
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
download_space_as_png: function(space) {
|
|
|
|
|
window.open(ENV.apiEndpoint + "/api/spaces/" + space._id + "/png");
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
download_space_as_pdf: function(space) {
|
|
|
|
|
this.global_spinner = true;
|
|
|
|
|
get_resource("/spaces/" + space._id + "/pdf", function(o) {
|
|
|
|
|
this.global_spinner = false;
|
|
|
|
|
location.href = o.url;
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
this.global_spinner = false;
|
|
|
|
|
alert("PDF export problem (" + xhr.status + ").");
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
download_space_as_zip: function(space) {
|
|
|
|
|
this.global_spinner = true;
|
|
|
|
|
|
|
|
|
|
get_resource("/spaces/" + space._id + "/zip", function(o) {
|
|
|
|
|
|
|
|
|
|
this.global_spinner = false;
|
|
|
|
|
location.href = o.url;
|
|
|
|
|
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
this.global_spinner = false;
|
|
|
|
|
alert("ZIP export problem (" + xhr.status + ").");
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
download_space_as_list: function(space) {
|
|
|
|
|
this.global_spinner = true;
|
|
|
|
|
location.href = "/api/spaces/" + space._id + "/list";
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
duplicate_space_into_folder: function() {
|
|
|
|
|
load_writable_folders( function(folders){
|
|
|
|
|
this.duplicate_folders = _.sortBy(folders, function (folder) { return folder.name; });
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
duplicate_folder_confirm: function() {
|
|
|
|
|
var folderId = this.duplicate_folder_id;
|
|
|
|
|
var idx = _.findIndex(this.duplicate_folders, function(s) { return s._id == folderId;});
|
|
|
|
|
if (idx<0) idx = 0;
|
|
|
|
|
var folder = this.duplicate_folders[idx];
|
|
|
|
|
console.log("df f",folder);
|
|
|
|
|
if (!folder) return;
|
|
|
|
|
|
|
|
|
|
duplicate_space(this.active_space, folder._id, function(new_space) {
|
|
|
|
|
|
|
|
|
|
this.duplicate_folders = [];
|
|
|
|
|
this.duplicate_folder = null;
|
|
|
|
|
|
|
|
|
|
smoke.quiz(__("duplicate_success", this.active_space.name, folder.name), function(e, test){
|
|
|
|
|
if (e == __("goto_space", new_space.name)){
|
|
|
|
|
this.redirect_to("/spaces/" + new_space._id);
|
|
|
|
|
}else if (e == __("goto_folder", folder.name)){
|
|
|
|
|
this.redirect_to("/folders/" + folder._id);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), {
|
|
|
|
|
button_1: __("goto_space", new_space.name),
|
|
|
|
|
button_2: __("goto_folder", folder.name),
|
|
|
|
|
button_cancel:__("stay_here")
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}.bind(this), function(xhr){
|
|
|
|
|
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
smoke.prompt("error: " + xhr.statusText);
|
|
|
|
|
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
toggle_follow_mode: function() {
|
|
|
|
|
this.deselect();
|
|
|
|
|
this.follow_mode = !this.follow_mode;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
toggle_present_mode: function() {
|
|
|
|
|
this.deselect();
|
|
|
|
|
this.present_mode = !this.present_mode;
|
|
|
|
|
if (this.present_mode) {
|
|
|
|
|
//this.go_to_first_zone();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
meta_last_seen_key: function() {
|
|
|
|
|
var seen_key = "meta-seen-";
|
|
|
|
|
if (this.active_view == 'space') {
|
|
|
|
|
if (!this.active_space) return "invalid";
|
|
|
|
|
seen_key += this.active_space._id;
|
|
|
|
|
} else if (this.active_view == 'folders') {
|
|
|
|
|
if (!this.active_folder) return "invalid";
|
|
|
|
|
seen_key += this.active_folder._id;
|
|
|
|
|
}
|
|
|
|
|
return seen_key;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
toggle_meta: function() {
|
|
|
|
|
this.meta_visible = !this.meta_visible;
|
|
|
|
|
if (this.meta_visible) {
|
|
|
|
|
var seen_key = this.meta_last_seen_key();
|
|
|
|
|
|
|
|
|
|
if ("localStorage" in window && localStorage) {
|
|
|
|
|
localStorage[seen_key] = new Date().getTime();
|
|
|
|
|
console.log("seen_key: ",seen_key,localStorage[seen_key]);
|
|
|
|
|
this.meta_last_seen = localStorage[seen_key];
|
|
|
|
|
}
|
|
|
|
|
this.meta_unseen = 0;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
toggle_space_access_mode: function() {
|
|
|
|
|
this.access_settings_space.access_mode = (this.access_settings_space.access_mode=="public")?"private":"public";
|
|
|
|
|
save_space(this.access_settings_space);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space_access_mode: function(evt) {
|
|
|
|
|
// FIXME really bad that i have to do this manually. why is the
|
|
|
|
|
// value not already updated when v-on="change" is fired?!
|
|
|
|
|
this.access_settings_space.access_mode = evt.currentTarget.value;
|
|
|
|
|
save_space(this.access_settings_space);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save_space_editors_locking: function(evt) {
|
|
|
|
|
// FIXME same issue as above
|
|
|
|
|
this.access_settings_space.editors_locking = evt.currentTarget.checked;
|
|
|
|
|
save_space(this.access_settings_space);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
create_join_link: function() {
|
|
|
|
|
create_join_link(this.active_space._id, this.join_link_role, function(result) {
|
|
|
|
|
this.active_join_link = "https://"+location.host+"/invitations/"+result.code+"/accept";
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
delete_join_link: function() {
|
|
|
|
|
get_join_link(this.active_space._id, function(result) {
|
|
|
|
|
if (result && result.length) {
|
|
|
|
|
delete_join_link(result[result.length-1]._id, function() {
|
|
|
|
|
this.active_join_link = "";
|
|
|
|
|
}.bind(this));
|
|
|
|
|
}
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
invite_member: function(space, emails_text, txt, role) {
|
|
|
|
|
this.invite_email_error = null;
|
|
|
|
|
|
|
|
|
|
var emails = emails_text.split(",");
|
|
|
|
|
var displayed_success = false;
|
|
|
|
|
|
|
|
|
|
_.each(emails, function(email) {
|
|
|
|
|
email = email.trim();
|
|
|
|
|
|
|
|
|
|
if (!validateEmail(email)) {
|
|
|
|
|
this.invite_email_error = "Please enter a valid address."
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var m = {
|
|
|
|
|
email_invited: email,
|
|
|
|
|
personal_message: txt,
|
|
|
|
|
role: role
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
create_membership(space, m, function(m) {
|
|
|
|
|
this.access_settings_memberships.push(m);
|
|
|
|
|
console.log("membership created:", m);
|
|
|
|
|
this.editors_section="list";
|
|
|
|
|
|
|
|
|
|
if (!displayed_success) {
|
|
|
|
|
displayed_success = true;
|
|
|
|
|
smoke.alert("Invitation(s) sent.");
|
|
|
|
|
this.invite_email = "";
|
|
|
|
|
this.invite_message = "";
|
|
|
|
|
}
|
|
|
|
|
}.bind(this), function(xhr){
|
|
|
|
|
|
|
|
|
|
text = JSON.stringify(xhr.responseText);
|
|
|
|
|
smoke.alert("Error: "+text);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
update_member: function(space, m, role) {
|
|
|
|
|
m.role = role;
|
|
|
|
|
save_membership(space, m, function() {
|
|
|
|
|
console.log("saved")
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// revoke
|
|
|
|
|
remove_member: function(space, m) {
|
|
|
|
|
delete_membership(space, m, function() {
|
|
|
|
|
this.access_settings_memberships.splice(this.access_settings_memberships.indexOf(m), 1);
|
|
|
|
|
}.bind(this), function(xhr) {
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
history_back: function() {
|
|
|
|
|
window.history.back();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
create_space_comment: function(comment) {
|
|
|
|
|
if (!comment.length) return;
|
|
|
|
|
|
|
|
|
|
var data = {
|
|
|
|
|
space: this.active_space._id,
|
|
|
|
|
message: comment,
|
|
|
|
|
editor_name: this.guest_nickname,
|
|
|
|
|
user: this.user
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
save_comment(this.active_space._id, data, function(comment) {
|
|
|
|
|
console.log("comment saved: ",comment.created_at);
|
|
|
|
|
this.active_space_messages.push(comment);
|
|
|
|
|
this.space_comment = "";
|
|
|
|
|
}.bind(this), function(xhr){
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
remove_space_comment: function(comment) {
|
|
|
|
|
delete_comment(this.active_space._id, comment._id, function() {
|
|
|
|
|
console.log("comment id:",comment._id);
|
|
|
|
|
this.active_space_messages = _.filter(this.active_space_messages, function(c){return c._id!=comment._id;});
|
|
|
|
|
}.bind(this), function(xhr){
|
|
|
|
|
console.error(xhr);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
emojified_comment: function(comment) {
|
|
|
|
|
return twemoji.parse(comment);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
set_folder_sorting: function(key,reverse) {
|
|
|
|
|
this.folder_sorting = key;
|
|
|
|
|
this.folder_reverse = reverse?-1:1;
|
|
|
|
|
|
|
|
|
|
console.log(key, reverse);
|
|
|
|
|
|
|
|
|
|
if ("localStorage" in window) {
|
|
|
|
|
localStorage["folder_sorting_"+this.active_folder._id] = this.folder_sorting;
|
|
|
|
|
localStorage["folder_reverse_"+this.active_folder._id] = this.folder_reverse;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
activate_space_info_section: function(id) {
|
|
|
|
|
this.space_info_section = id;
|
|
|
|
|
this.editors_section = "list";
|
|
|
|
|
|
|
|
|
|
if (id == "versions") {
|
|
|
|
|
// load space versions
|
|
|
|
|
load_spaces(this.active_space._id, null, function(space_with_children) {
|
|
|
|
|
this.active_space.children = space_with_children.children;
|
|
|
|
|
console.log("loaded: ",space_with_children);
|
|
|
|
|
}.bind(this));
|
|
|
|
|
} else if (id == "info") {
|
|
|
|
|
// load replies
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handle_folder_drop: function(evt, dest) {
|
|
|
|
|
try {
|
|
|
|
|
var source = JSON.parse(evt.dataTransfer.getData("application/json"));
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!source || !source._id || !source.parent_space_id || !dest._id) return;
|
|
|
|
|
|
|
|
|
|
if (source._id==dest._id) return;
|
|
|
|
|
|
|
|
|
|
if (dest.space_type!="folder") {
|
|
|
|
|
alert("Spaces can only be moved into folders.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
source.parent_space_id = dest._id;
|
|
|
|
|
save_space(source, function() {
|
|
|
|
|
var idx = _.findIndex(this.active_folder.children, function(s) { return s._id == source._id;});
|
|
|
|
|
if (idx>=0) {
|
|
|
|
|
this.active_folder.children.splice(idx,1);
|
|
|
|
|
console.log("spliced: ",idx);
|
|
|
|
|
}
|
|
|
|
|
}.bind(this));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
activate_access: function() {
|
|
|
|
|
this.activate_modal("access");
|
|
|
|
|
//this.meta_visible = false;
|
|
|
|
|
|
|
|
|
|
if (this.active_space._id) {
|
|
|
|
|
this.access_settings_space = this.active_space;
|
|
|
|
|
} else if (this.active_folder && this.active_folder._id) {
|
|
|
|
|
this.access_settings_space = this.active_folder;
|
|
|
|
|
} else {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.access_settings_memberships = this.active_space_memberships;
|
|
|
|
|
},
|
|
|
|
|
close_access: function() {
|
|
|
|
|
this.close_modal();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
show_offline_help: function() {
|
|
|
|
|
smoke.confirm(__('was_offline'), function(confirmed) {
|
|
|
|
|
if (!confirmed) return;
|
|
|
|
|
location.reload();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|