diff --git a/.gitignore b/.gitignore index 23e38016c2..67787e1768 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ provision.sh feeds/recent.rss .eslintcache .svn +cordova/ +plugins/ +config-* logs/ @@ -69,4 +72,8 @@ package-lock.json /package.json *.mongodb link-plugins.sh -test.sh \ No newline at end of file + +# Isekai addition +makeCordova.sh +rebuild.sh +test.sh diff --git a/install/package.json b/install/package.json index a25c262ff1..91ed420492 100644 --- a/install/package.json +++ b/install/package.json @@ -192,4 +192,4 @@ "url": "https://github.com/barisusakli" } ] -} \ No newline at end of file +} diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index d7fcac6eb5..edf057d774 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -12,10 +12,30 @@ ajaxify.widgets = { render: render }; let retry = true; let previousBodyClass = ''; + ajaxify.loading = false; ajaxify.count = 0; ajaxify.currentPage = null; + + var _throttleTimer = null; + var _cachedRequest = null; + function startThrottle(...args) { + if (typeof args[0] === "string") { + _cachedRequest = args; + } + if (_cachedRequest && !_throttleTimer) { + _throttleTimer = setTimeout(() => { + if (_cachedRequest) { + ajaxify.go.apply(ajaxify, _cachedRequest); + _cachedRequest = null; + } + _throttleTimer = null; + }, 500); + } + } ajaxify.go = function (url, callback, quiet) { + ajaxify.loading = true; + // Automatically reconnect to socket and re-ajaxify on success if (!socket.connected) { app.reconnect(); @@ -32,11 +52,13 @@ ajaxify.widgets = { render: render }; // Abort subsequent requests if clicked multiple times within a short window of time if (ajaxifyTimer && (Date.now() - ajaxifyTimer) < 500) { + startThrottle(url, callback, quiet); return true; } ajaxifyTimer = Date.now(); if (ajaxify.handleRedirects(url)) { + ajaxify.loading = false; return true; } @@ -59,6 +81,7 @@ ajaxify.widgets = { render: render }; // If any listeners alter url and set it to an empty string, abort the ajaxification if (url === null) { hooks.fire('action:ajaxify.end', { url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title }); + ajaxify.loading = false; return false; } @@ -72,6 +95,7 @@ ajaxify.widgets = { render: render }; (parseInt(err.data.status, 10) !== 302 && parseInt(err.data.status, 10) !== 308) )) { ajaxify.updateHistory(url, quiet); + ajaxify.loading = false; } if (err) { @@ -138,6 +162,8 @@ ajaxify.widgets = { render: render }; const data = err.data; const textStatus = err.textStatus; + ajaxify.loading = false; + if (data) { let status = parseInt(data.status, 10); if ([400, 403, 404, 500, 502, 504].includes(status)) { @@ -307,6 +333,18 @@ ajaxify.widgets = { render: render }; hooks.fire('action:ajaxify.contentLoaded', { url: url, tpl: tpl_url }); app.processPage(); + + ajaxify.loading = false; + + if (_cachedRequest) { + if (_throttleTimer) { + clearTimeout(_throttleTimer); + _throttleTimer = null; + } + ajaxifyTimer = 0; + ajaxify.go(_cachedRequest[0], _cachedRequest[1], true); + _cachedRequest = null; + } }; ajaxify.parseData = () => { @@ -516,8 +554,12 @@ $(document).ready(function () { // Special handling for urls with hashes if (window.location.pathname === this.pathname && this.hash.length) { window.location.hash = this.hash; - } else if (ajaxify.go(pathname)) { - e.preventDefault(); + } else { + var isReplaceLink = $this.parent('li').parent('.nav.nav-pills').length > 0 || + $this.parent('li').parent('.pagination').length > 0 + if (ajaxify.go(pathname, null, isReplaceLink)) { + e.preventDefault(); + } } } else if (window.location.pathname !== config.relative_path + '/outgoing') { if (config.openOutgoingLinksInNewTab && $.contains(contentEl, this)) { diff --git a/src/controllers/category.js b/src/controllers/category.js index d233dbb369..3848f2f0e0 100644 --- a/src/controllers/category.js +++ b/src/controllers/category.js @@ -50,7 +50,7 @@ categoryController.get = async function (req, res, next) { return helpers.notAllowed(req, res); } - if (!res.locals.isAPI && !req.params.slug && (categoryFields.slug && categoryFields.slug !== `${cid}/`)) { + if (!res.locals.isAPI && !req.params.slug && (categoryFields.slug && categoryFields.slug !== `${cid}`)) { return helpers.redirect(res, `/category/${categoryFields.slug}?${qs.stringify(req.query)}`, true); } diff --git a/src/controllers/topics.js b/src/controllers/topics.js index a92570b8c8..ef6379b7a1 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -62,7 +62,7 @@ topicsController.get = async function getTopic(req, res, next) { postIndex = await topics.getUserBookmark(tid, req.uid); } - if (!res.locals.isAPI && (!req.params.slug || topicData.slug !== `${tid}/${req.params.slug}`) && (topicData.slug && topicData.slug !== `${tid}/`)) { + if (!res.locals.isAPI && (!req.params.slug || topicData.slug !== `${tid}/${req.params.slug}`) && (topicData.slug && topicData.slug !== `${tid}`)) { return helpers.redirect(res, `/topic/${topicData.slug}${postIndex ? `/${postIndex}` : ''}${generateQueryString(req.query)}`, true); } diff --git a/src/user/profile.js b/src/user/profile.js index fc238ff87c..76c61191db 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -173,13 +173,13 @@ module.exports = function (User) { } function isFullnameValid(data) { - if (data.fullname && (validator.isURL(data.fullname) || data.fullname.length > 255)) { + if (data.fullname && data.fullname.length > 255) { throw new Error('[[error:invalid-fullname]]'); } } function isLocationValid(data) { - if (data.location && (validator.isURL(data.location) || data.location.length > 255)) { + if (data.location && data.location.length > 255) { throw new Error('[[error:invalid-location]]'); } }