From dd7746a2fd615109806c5fed2aa1bc3000aa68b8 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 6 Apr 2021 12:12:12 +0200 Subject: [PATCH] Calendar fixes --- www/calendar/inner.js | 13 ++- www/common/common-util.js | 12 +++ www/common/outer/async-store.js | 10 +- www/common/outer/calendar.js | 165 +++++++++++++++++++------------- 4 files changed, 122 insertions(+), 78 deletions(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index 2fd9849b5..698e60035 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -56,6 +56,7 @@ Messages.calendar_today = "Today"; Messages.calendar_deleteConfirm = "Are you sure you want to delete this calendar from your account?"; Messages.calendar_deleteTeamConfirm = "Are you sure you want to delete this calendar from this team?"; Messages.calendar_deleteOwned = " It will still be visible for the users it has been shared with."; +Messages.calendar_errorNoCalendar = "No calendar selected!"; var onCalendarsUpdate = Util.mkEvent(); @@ -157,6 +158,7 @@ Messages.calendar_deleteOwned = " It will still be visible for the users it has if (!cal) { return; } cal.clear(); + cal.setCalendars(getCalendars()); cal.createSchedules(getSchedules(), true); cal.render(); }; @@ -166,7 +168,6 @@ Messages.calendar_deleteOwned = " It will still be visible for the users it has // Is it a new calendar? var isNew = !APP.calendars[data.id]; - console.error(data, data.content.metadata.color); if (data.deleted) { // Remove this calendar delete APP.calendars[data.id]; @@ -177,8 +178,6 @@ Messages.calendar_deleteOwned = " It will still be visible for the users it has // If calendar if initialized, update it if (!cal) { return; } - console.error('OK'); - cal.setCalendars(getCalendars()); onCalendarsUpdate.fire(); renderCalendar(); }; @@ -249,6 +248,7 @@ Messages.calendar_deleteOwned = " It will still be visible for the users it has jscolorL.show(); }); if (md.color) { jscolorL.fromString(md.color); } + else { jscolorL.fromString(Util.getRandomColor()); } var form = h('div', [ labelTitle, @@ -593,10 +593,15 @@ Messages.calendar_deleteOwned = " It will still be visible for the users it has $el.find('input').attr('autocomplete', 'off'); $el.find('.tui-full-calendar-dropdown-button').addClass('btn btn-secondary'); $el.find('.tui-full-calendar-popup-close').addClass('btn btn-cancel fa fa-times cp-calendar-close').empty(); + if ($el.find('.tui-full-calendar-hide.tui-full-calendar-dropdown').length) { + $el.hide(); + UI.warn(Messages.calendar_errorNoCalendar); + return; + } var isUpdate = Boolean($el.find('#tui-full-calendar-schedule-title').val()); if (isUpdate) { $el.find('.tui-full-calendar-dropdown-button').attr('disabled', 'disabled').off('click'); - $el.find('.tui-full-calendar-dropdown-menu').addClass('cp-forcehide'); + $el.find('.tui-full-calendar-dropdown-menu').addClass('cp-forcehide'); } }; var observer = new MutationObserver(function(mutations) { diff --git a/www/common/common-util.js b/www/common/common-util.js index 36ae5cf64..c4e513117 100644 --- a/www/common/common-util.js +++ b/www/common/common-util.js @@ -585,6 +585,18 @@ return isEmoji(emojis[0])? emojis[0]: str[0]; }; + Util.getRandomColor = function (light) { + var getColor = function () { + if (light) { + return Math.floor(Math.random() * 156) + 70; + } + return Math.floor(Math.random() * 200) + 25; + }; + return '#' + getColor().toString(16) + + getColor().toString(16) + + getColor().toString(16); +}; + if (typeof(module) !== 'undefined' && module.exports) { module.exports = Util; } else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) { diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index a58c1eb6f..2a494e112 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -574,18 +574,10 @@ define([ }; // Get or create the user color for the cursor position - var getRandomColor = function () { - var getColor = function () { - return Math.floor(Math.random() * 156) + 70; - }; - return '#' + getColor().toString(16) + - getColor().toString(16) + - getColor().toString(16); - }; Store.getUserColor = function () { var color = Util.find(store, ['proxy', 'settings', 'general', 'cursor', 'color']); if (!color) { - color = getRandomColor(); + color = Util.getRandomColor(true); Store.setAttribute(null, { attr: ['general', 'cursor', 'color'], value: color diff --git a/www/common/outer/calendar.js b/www/common/outer/calendar.js index 03a497cdf..9c36aa1c7 100644 --- a/www/common/outer/calendar.js +++ b/www/common/outer/calendar.js @@ -4,10 +4,11 @@ define([ '/common/common-constants.js', '/common/common-realtime.js', '/customize/messages.js', + '/bower_components/nthen/index.js', '/bower_components/chainpad-listmap/chainpad-listmap.js', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad/chainpad.dist.js', -], function (Util, Hash, Constants, Realtime, Messages, Listmap, Crypto, ChainPad) { +], function (Util, Hash, Constants, Realtime, Messages, nThen, Listmap, Crypto, ChainPad) { var Calendar = {}; @@ -64,6 +65,15 @@ ctx.calendars[channel] = { */ + var getStore = function (ctx, id) { + if (!id || id === 1) { + return ctx.store; + } + var m = ctx.store.modules && ctx.store.modules.team; + if (!m) { return; } + return m.getTeam(id); + }; + var makeCalendar = function () { var hash = Hash.createRandomHash('calendar'); var secret = Hash.getSecrets('calendar', hash); @@ -150,54 +160,88 @@ ctx.calendars[channel] = { var secret = Hash.getSecrets('calendar', parsed.hash); var crypto = Crypto.createEncryptor(secret.keys); - // Set the owners as the first store opening it. We don't know yet if it's a new or - // existing calendar. "owners' will be ignored if the calendar already exists. - var edPublic; - if (teamId === 1) { - edPublic = ctx.store.proxy.edPublic; - } else { - var teams = ctx.store.modules.team && ctx.store.modules.team.getTeamsData(); - var team = teams && teams[teamId]; - edPublic = team ? team.edPublic : undefined; - } - - var config = { - data: {}, - network: ctx.store.network, // XXX offline - channel: secret.channel, - crypto: crypto, - owners: [edPublic], - ChainPad: ChainPad, - validateKey: secret.keys.validateKey || undefined, - userName: 'calendar', - classic: true - }; - - console.error(channel, config); - var lm = Listmap.create(config); - c.lm = lm; - var proxy = c.proxy = lm.proxy; - - lm.proxy.on('ready', function () { - c.ready = true; - if (!proxy.metadata) { - proxy.metadata = { - color: data.color, - title: data.title - }; + nThen(function (waitFor) { + // XXX Check if channel exists + // XXX Get pad metadata (offline??) + + }).nThen(function () { + // Set the owners as the first store opening it. We don't know yet if it's a new or + // existing calendar. "owners' will be ignored if the calendar already exists. + var edPublic; + if (teamId === 1) { + edPublic = ctx.store.proxy.edPublic; + } else { + var teams = ctx.store.modules.team && ctx.store.modules.team.getTeamsData(); + var team = teams && teams[teamId]; + edPublic = team ? team.edPublic : undefined; } - setTimeout(update); - if (cb) { cb(null, lm.proxy); } - }).on('change', [], function () { - if (!c.ready) { return; } - setTimeout(update); - }).on('change', ['metadata'], function () { - // if title or color have changed, update our local values - var md = proxy.metadata; - if (!md || !md.title || !md.color) { return; } - updateLocalCalendars(ctx, c, md); - }).on('error', function (info) { - if (info && info.error) { cb(info); } + + var config = { + data: {}, + network: ctx.store.network, // XXX offline + channel: secret.channel, + crypto: crypto, + owners: [edPublic], + ChainPad: ChainPad, + validateKey: secret.keys.validateKey || undefined, + userName: 'calendar', + classic: true + }; + + console.error(channel, config); + var lm = Listmap.create(config); + c.lm = lm; + var proxy = c.proxy = lm.proxy; + + var onDeleted = function () { + nThen(function (w) { + c.stores.forEach(function (storeId) { + var store = getStore(ctx, storeId); + if (!store || !store.rpc || !store.proxy.calendars) { return; } + delete store.proxy.calendars[channel]; + var unpin = store.unpin || ctx.unpinPads; + unpin([channel], function (res) { + if (res && res.error) { console.error(res.error); } + }); + ctx.Store.onSync(storeId, w()); + }); + }).nThen(function () { + lm.stop(); + c.stores = []; + sendUpdate(ctx, c); + delete ctx.calendars[channel]; + }); + }; + + lm.proxy.on('ready', function () { + c.ready = true; + if (!proxy.metadata) { + if (!cfg.isNew) { + // XXX no metadata on an existing calendar: deleted calendar + return void onDeleted(); + } + proxy.metadata = { + color: data.color, + title: data.title + }; + } + setTimeout(update); + if (cb) { cb(null, lm.proxy); } + }).on('change', [], function () { + if (!c.ready) { return; } + setTimeout(update); + }).on('change', ['metadata'], function () { + // if title or color have changed, update our local values + var md = proxy.metadata; + if (!md || !md.title || !md.color) { return; } + updateLocalCalendars(ctx, c, md); + }).on('error', function (info) { + if (!info || !info.error) { return; } + if (info.error === "EDELETED" ) { + return void onDeleted(); + } + cb(info); + }); }); }; var openChannels = function (ctx) { @@ -235,15 +279,6 @@ ctx.calendars[channel] = { }); }; - var getStore = function (ctx, id) { - if (!id || id === 1) { - return ctx.store; - } - var m = ctx.store.modules && ctx.store.modules.team; - if (!m) { return; } - return m.getTeam(id); - }; - var createCalendar = function (ctx, data, cId, cb) { var store = getStore(ctx, data.teamId); if (!store) { return void cb({error: "NO_STORE"}); } @@ -256,7 +291,8 @@ ctx.calendars[channel] = { cal.title = data.title; openChannel(ctx, { storeId: store.id || 1, - data: cal + data: cal, + isNew: true }, function (err, proxy) { if (err) { // Can't open this channel, don't store it @@ -267,9 +303,7 @@ ctx.calendars[channel] = { c[cal.channel] = cal; var pin = store.pin || ctx.pinPads; pin([cal.channel], function (res) { - if (res && res.error) { - console.error(res.error); - } + if (res && res.error) { console.error(res.error); } }); ctx.Store.onSync(store.id, cb); }); @@ -302,9 +336,7 @@ ctx.calendars[channel] = { // Unpin var unpin = store.unpin || ctx.unpinPads; unpin([id], function (res) { - if (res && res.error) { - console.error(res.error); - } + if (res && res.error) { console.error(res.error); } }); // Clear/update ctx data @@ -332,7 +364,10 @@ ctx.calendars[channel] = { if (!c) { return void cb({error: "ENOENT"}); } c.proxy.content = c.proxy.content || {}; c.proxy.content[data.id] = data; - Realtime.whenRealtimeSyncs(c.lm.realtime, cb); + Realtime.whenRealtimeSyncs(c.lm.realtime, function () { + sendUpdate(ctx, c); + cb(); + }); }; var updateEvent = function (ctx, data, cId, cb) { if (!data || !data.ev) { return void cb({error: 'EINVAL'}); }