UNPKG

meemo-app

Version:

A personal ideas, notes or links manager

389 lines (294 loc) 13.7 kB
(function () { 'use strict'; var g_server = location.origin; var g_token = localStorage.token || ''; function guid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } function errorWrapper(callback) { return function (error, result) { if (error && error.status === 401) return window.Guacamoly.Core.onAuthFailure(); callback(error, result); }; } function url(path) { return g_server + path; } function origin() { return g_server; } function token() { return g_token; } function Thing(id, createdAt, modifiedAt, tags, content, richContent, attachments, isPublic, isArchived, isSticky) { this.id = id; this.createdAt = createdAt || 0; this.modifiedAt = modifiedAt || 0; this.tags = tags || []; this.content = content; this.edit = false; this.richContent = richContent; this.attachments = attachments || []; this.public = !!isPublic; this.archived = !!isArchived; this.sticky = !!isSticky; } function ThingsApi() { this._addCallbacks = []; this._editCallbacks = []; this._delCallbacks = []; this._operation = ''; this._query = null; } ThingsApi.prototype.get = function (filter, isArchived, callback) { var that = this; var u = url('/api/things'); var operation = guid(); this._operation = operation; this._query = {}; if (filter) this._query.filter = filter; if (isArchived) this._query.archived = true; // TODO add ui to toggle this based on user preference this._query.sticky = true; this._query.skip = 0; this._query.limit = 10; superagent.get(u).query(this._query).end(errorWrapper(function (error, result) { // ignore this if we moved on if (that._operation !== operation) { console.log('ignore this call'); return; } if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); var tmp = result.body.things.map(function (thing) { return new Thing(thing._id, new Date(thing.createdAt).getTime(), new Date(thing.modifiedAt).getTime(), thing.tags, thing.content, thing.richContent, thing.attachments, thing.public, thing.archived, thing.sticky); }); // update skip for fetch more call that._query.skip += result.body.things.length; callback(null, tmp); })); }; ThingsApi.prototype.fetchMore = function (callback) { var that = this; var u = url('/api/things'); if (!this._query) return callback(new Error('no previous query')); superagent.get(u).query(this._query).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); var tmp = result.body.things.map(function (thing) { return new Thing(thing._id, new Date(thing.createdAt).getTime(), new Date(thing.modifiedAt).getTime(), thing.tags, thing.content, thing.richContent, thing.attachments, thing.public, thing.archived, thing.sticky); }); // update skip for next call that._query.skip += result.body.things.length; callback(null, tmp); })); }; ThingsApi.prototype.add = function (content, attachments, callback) { var that = this; superagent.post(url('/api/things')).send({ content: content, attachments: attachments }).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 201) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); var tmp = result.body.thing; var thing = new Thing(tmp._id, new Date(tmp.createdAt).getTime(), new Date(tmp.modifiedAt).getTime(), tmp.tags, tmp.content, tmp.richContent, tmp.attachments, tmp.public, tmp.archived, tmp.sticky); that._addCallbacks.forEach(function (callback) { setTimeout(callback.bind(null, thing), 0); }); callback(null, thing); })); }; ThingsApi.prototype.edit = function (thing, callback) { var that = this; superagent.put(url('/api/things/' + thing.id)).send(thing).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 201) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); that._editCallbacks.forEach(function (callback) { setTimeout(callback.bind(null, thing), 0); }); callback(null, result.body.thing); })); }; ThingsApi.prototype.del = function (thing, callback) { var that = this; superagent.del(url('/api/things/' + thing.id)).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); that._delCallbacks.forEach(function (callback) { setTimeout(callback.bind(null, thing), 0); }); callback(null); })); }; ThingsApi.prototype.getPublicThing = function (userId, thingId, callback) { superagent.get(url('/api/public/' + userId + '/things/' + thingId)).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); var thing = result.body.thing; callback(null, new Thing(thing._id, new Date(thing.createdAt).getTime(), new Date(thing.modifiedAt).getTime(), thing.tags, thing.content, thing.richContent, thing.attachments, thing.public)); })); }; ThingsApi.prototype.getPublic = function (userId, filter, callback) { var that = this; var u = url('/api/public/' + userId + '/things'); var operation = guid(); this._operation = operation; this._query = {}; if (filter) this._query.filter = filter; this._query.skip = 0; this._query.limit = 10; superagent.get(u).query(this._query).end(errorWrapper(function (error, result) { // ignore this if we moved on if (that._operation !== operation) { console.log('ignore this call'); return; } if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); var tmp = result.body.things.map(function (thing) { return new Thing(thing._id, new Date(thing.createdAt).getTime(), new Date(thing.modifiedAt).getTime(), thing.tags, thing.content, thing.richContent, thing.attachments, thing.public); }); // update skip for fetch more call that._query.skip += result.body.things.length; callback(null, tmp); })); }; ThingsApi.prototype.fetchMorePublic = function (userId, callback) { var that = this; var u = url('/api/public/' + userId + '/things'); if (!this._query) return callback(new Error('no previous query')); superagent.get(u).query(this._query).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); var tmp = result.body.things.map(function (thing) { return new Thing(thing._id, new Date(thing.createdAt).getTime(), new Date(thing.modifiedAt).getTime(), thing.tags, thing.content, thing.richContent, thing.attachments, thing.public); }); // update skip for next call that._query.skip += result.body.things.length; callback(null, tmp); })); }; ThingsApi.prototype.import = function (formData, callback) { superagent.post(url('/api/import')).send(formData).end(errorWrapper(function (error, result) { if (error) return callback(error); callback(null); })); }; ThingsApi.prototype.uploadFile = function (formData, progressHandler, callback) { superagent.post(url('/api/files')).send(formData).on('progress', function (event) { if (event.loaded && event.total) progressHandler(event.loaded / event.total); }).end(errorWrapper(function (error, result) { if (error) return callback(error); callback(null, result.body); })); }; ThingsApi.prototype.onAdded = function (callback) { this._addCallbacks.push(callback); }; ThingsApi.prototype.onEdited = function (callback) { this._editCallbacks.push(callback); }; ThingsApi.prototype.onDeleted = function (callback) { this._delCallbacks.push(callback); }; ThingsApi.prototype.export = function () { window.location.href = url('/api/export'); }; function SettingsApi() { this._changeCallbacks = []; } SettingsApi.prototype.save = function (data, callback) { var that = this; superagent.post(url('/api/settings')).send({ settings: data }).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 202) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); that._changeCallbacks.forEach(function (callback) { setTimeout(callback.bind(null, data), 0); }); callback(null); })); }; SettingsApi.prototype.get = function (callback) { superagent.get(url('/api/settings')).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); // just ensure we have defaults if (!result.body.settings.title) result.body.settings.title = 'Meemo'; if (typeof result.body.settings.wide === 'undefined') result.body.settings.wide = false; if (typeof result.body.settings.wideNavbar === 'undefined') result.body.settings.wideNavbar = true; if (!result.body.settings.backgroundImageDataUrl) result.body.settings.backgroundImageDataUrl = ''; if (typeof result.body.settings.keepPositionAfterEdit === 'undefined') result.body.settings.keepPositionAfterEdit = false; if (typeof result.body.settings.publicBackground === 'undefined') result.body.settings.publicBackground = false; if (typeof result.body.settings.showTagSidebar === 'undefined') result.body.settings.showTagSidebar = false; callback(null, result.body.settings); })); }; SettingsApi.prototype.onChanged = function (callback) { this._changeCallbacks.push(callback); }; function TagsApi() {} TagsApi.prototype.get = function (callback) { superagent.get(url('/api/tags')).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); result.body.tags.sort(function (a, b) { return a.name > b.name; }); callback(null, result.body.tags); })); }; function SessionApi() {} SessionApi.prototype.login = function (username, password, callback) { superagent.post(g_server + '/api/login').send({ username: username, password: password }).end(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 201) return callback(error); g_token = result.body.token; localStorage.token = g_token; callback(null, result.body.user); }); }; SessionApi.prototype.logout = function () { superagent.get(url('/api/logout')).end(function (error, result) { if (error && !error.response) console.error(error); if (result.status !== 200) console.error('Logout failed.', result.status, result.text); g_token = ''; delete localStorage.token; window.Guacamoly.Core.onLogout(); }); }; SessionApi.prototype.profile = function (callback) { superagent.get(url('/api/profile')).end(errorWrapper(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Failed: ' + result.status + '. ' + result.text)); callback(null, result.body); })); }; function UsersApi() {} UsersApi.prototype.list = function (callback) { superagent.get(url('/api/users')).end(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('User listing failed. ' + result.status + '. ' + result.text)); callback(null, result.body.users); }); }; UsersApi.prototype.publicProfile = function (userId, callback) { superagent.get(url('/api/users/' + userId)).end(function (error, result) { if (error && !error.response) return callback(error); if (result.status !== 200) return callback(new Error('Fetching public profile failed. ' + result.status + '. ' + result.text)); callback(null, result.body); }); }; window.Guacamoly = window.Guacamoly || {}; window.Guacamoly.Core = { onAuthFailure: function () {}, onLogout: function () {}, url: url, origin: origin, token: token, Thing: Thing, session: new SessionApi(), settings: new SettingsApi(), things: new ThingsApi(), tags: new TagsApi(), users: new UsersApi() }; })();