1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-29 18:19:44 +02:00

Semver based in-app news and update notification

Ignore semver.patch for Whats New notifications.

Use semver.major.minor.patch for Admin notifications.

Changed endpoint to /news.
This commit is contained in:
McMatts 2018-03-23 11:52:19 +00:00
parent 8d65c2d571
commit 0b85657536
8 changed files with 715 additions and 681 deletions

View file

@ -347,11 +347,8 @@ func (h *Handler) GetViewable(w http.ResponseWriter, r *http.Request) {
ctx := domain.GetRequestContext(r)
sp, err := h.Store.Space.GetViewable(ctx)
if err != nil {
// response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
return
}
response.WriteJSON(w, sp)
@ -369,15 +366,8 @@ func (h *Handler) GetAll(w http.ResponseWriter, r *http.Request) {
}
sp, err := h.Store.Space.GetAll(ctx)
if err != nil && err != sql.ErrNoRows {
response.WriteServerError(w, method, err)
if err != nil {
h.Runtime.Log.Error(method, err)
return
}
if len(sp) == 0 {
sp = []space.Space{}
}
response.WriteJSON(w, sp)

View file

@ -59,10 +59,14 @@ func (s Scope) Get(ctx domain.RequestContext, id string) (sp space.Space, err er
// PublicSpaces returns spaces that anyone can see.
func (s Scope) PublicSpaces(ctx domain.RequestContext, orgID string) (sp []space.Space, err error) {
sql := "SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label a where orgid=? AND type=1"
qry := "SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label a where orgid=? AND type=1"
err = s.Runtime.Db.Select(&sp, sql, orgID)
err = s.Runtime.Db.Select(&sp, qry, orgID)
if err == sql.ErrNoRows {
err = nil
sp = []space.Space{}
}
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("Unable to execute GetPublicFolders for org %s", orgID))
}
@ -104,13 +108,17 @@ func (s Scope) GetViewable(ctx domain.RequestContext) (sp []space.Space, err err
// GetAll for admin users!
func (s Scope) GetAll(ctx domain.RequestContext) (sp []space.Space, err error) {
sql := `
qry := `
SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label
WHERE orgid=?
ORDER BY name`
err = s.Runtime.Db.Select(&sp, sql, ctx.OrgID)
err = s.Runtime.Db.Select(&sp, qry, ctx.OrgID)
if err == sql.ErrNoRows {
err = nil
sp = []space.Space{}
}
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("failed space.GetAll org %s", ctx.OrgID))
}

View file

@ -35,7 +35,7 @@ func (s Scope) Add(ctx domain.RequestContext, u user.User) (err error) {
u.Created = time.Now().UTC()
u.Revised = time.Now().UTC()
_, err = ctx.Transaction.Exec("INSERT INTO user (refid, firstname, lastname, email, initials, password, salt, reset, lastversion, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
_, err = ctx.Transaction.Exec("INSERT INTO user (refid, firstname, lastname, email, initials, password, salt, reset, lastversion, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
u.RefID, u.Firstname, u.Lastname, strings.ToLower(u.Email), u.Initials, u.Password, u.Salt, "", u.LastVersion, u.Created, u.Revised)
if err != nil {

File diff suppressed because one or more lines are too long

View file

@ -25,7 +25,7 @@ export default Component.extend({
let self = this;
let cacheBuster = + new Date();
$.ajax({
url: `https://storage.googleapis.com/documize/downloads/updates/summary.html?cb=${cacheBuster}`,
url: `https://storage.googleapis.com/documize/news/summary.html?cb=${cacheBuster}`,
type: 'GET',
dataType: 'html',
success: function (response) {

View file

@ -48,7 +48,7 @@ export default Component.extend(ModalMixin, {
let self = this;
let cacheBuster = + new Date();
$.ajax({
url: `https://storage.googleapis.com/documize/downloads/updates/${version}.html?cb=${cacheBuster}`,
url: `https://storage.googleapis.com/documize/news/${version}.html?cb=${cacheBuster}`,
type: 'GET',
dataType: 'html',
success: function (response) {

View file

@ -13,6 +13,7 @@ import $ from 'jquery';
import { htmlSafe } from '@ember/string';
import { resolve } from 'rsvp';
import Service, { inject as service } from '@ember/service';
import miscUtil from '../utils/misc';
import config from '../config/environment';
import constants from '../utils/constants';
@ -28,6 +29,9 @@ export default Service.extend({
version: '',
message: '',
edition: 'Community',
// for major.minor semver release detection
// for bugfix releases, only admin is made aware of new release and end users see no Whats New messaging
updateAvailable: false,
valid: true,
allowAnonymousAccess: false,
authProvider: constants.AuthProvider.Documize,
@ -80,7 +84,7 @@ export default Service.extend({
let self = this;
let cacheBuster = + new Date();
$.getJSON(`https://storage.googleapis.com/documize/downloads/updates/meta.json?cb=${cacheBuster}`, function (versions) {
$.getJSON(`https://storage.googleapis.com/documize/news/meta.json?cb=${cacheBuster}`, function (versions) {
let cv = 'v' + versions.community.version;
let ev = 'v' + versions.enterprise.version;
let re = self.get('edition');
@ -90,12 +94,11 @@ export default Service.extend({
self.set('enterpriseLatest', ev);
self.set('updateAvailable', false); // set to true for testing
if (re === 'Community' && rv < cv) {
self.set('updateAvailable', true);
}
if (re === 'Enterprise' && rv < ev) {
self.set('updateAvailable', true);
}
let isNewCommunity = miscUtil.isNewVersion(rv, cv, true);
let isNewEnterprise = miscUtil.isNewVersion(rv, ev, true);
if (re === 'Community' && isNewCommunity) self.set('updateAvailable', true);
if (re === 'Enterprise' && isNewEnterprise) self.set('updateAvailable', true);
});
return response;

View file

@ -61,8 +61,41 @@ function insertAtCursor(myField, myValue) {
}
}
// Expects to receive semver version strings like "1.2.3" or "v1.2.3".
function isNewVersion(v1, v2, compareRevision) {
// Remove any "v" from version strings.
v1 = v1.replace('v', '');
v2 = v2.replace('v', '');
// Clean up strings.
v1 = v1.trim().toLowerCase();
v2 = v2.trim().toLowerCase();
// Format expected is "1.2.3".
let v1parts = v1.split('.');
let v2parts = v2.split('.');
// Must be 3+ parts per version string supporting
// v1.2.3 and v.1.2.3.beta1
if (v1parts.length < 3) return false;
if (v2parts.length < 3) return false;
// Compare Major and Minor verson parts.
if (v2parts[0] > v1parts[0]) return true;
if (v2parts[0] === v1parts[0] && v2parts[1] > v1parts[1]) return true;
if (compareRevision) {
if (v2parts[0] === v1parts[0] &&
v2parts[1] === v1parts[1] &&
v2parts[2] > v1parts[2]) return true;
}
return false;
}
export default {
interval,
wrapFunction,
insertAtCursor
insertAtCursor,
isNewVersion
};