diff --git a/client/css/style.css b/client/css/style.css index 03dfe793..78c0dba4 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -140,12 +140,24 @@ kbd { opacity: 0.6; } +.btn-sm { + padding: 4px 8px; + border-width: 1px; + letter-spacing: 0; + word-spacing: 0; + text-transform: none; +} + .container { margin: 80px auto; max-width: 480px; touch-action: pan-y; } +#help .container { + max-width: 600px; +} + ::-moz-placeholder { color: rgba(0, 0, 0, 0.35); opacity: 1; @@ -162,6 +174,7 @@ kbd { #js-copy-hack, #loading pre, #help, +#changelog, #windows .header .title, #windows .header .topic, #chat .messages { @@ -208,6 +221,7 @@ kbd { #chat .nick .from::before, #chat .action .from::before, #chat .toggle-button::after, +.changelog-version::before, .context-menu-item::before, #nick button::before, #image-viewer .previous-image-btn::before, @@ -1520,8 +1534,7 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */ display: table-row; } -#help .help-item, -#help .about { +#help .help-item { font-size: 14px; } @@ -1540,10 +1553,6 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */ margin-bottom: 0; } -#help .about { - line-height: 1.8; -} - .is-apple #help .key-all, #help .key-apple { display: none; @@ -1572,6 +1581,58 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */ grid-column-start: 2; } +#help .help-links { + margin-right: 20px; +} + +#changelog .container { + max-width: 740px; +} + +.changelog-text { + font-size: 16px; + line-height: 1.5; +} + +.changelog-text p { + margin-bottom: 16px; +} + +.window#changelog h3 { + font-size: 20px; + border-bottom: 1px solid #7f8c8d; + color: #7f8c8d; + margin: 30px 0 10px; + padding-bottom: 7px; +} + +.changelog-version { + display: block; + padding: 16px; + margin-bottom: 16px; + border-radius: 2px; + background-color: #d9edf7; + color: #31708f; +} + +.changelog-version::before { + margin-right: 6px; + content: "\f00c"; /* http://fontawesome.io/icon/check/ */ +} + +.changelog-version-new { + background-color: #dff0d8; + color: #3c763d; +} + +.changelog-version-new:hover { + color: #2b542c; +} + +.changelog-version-new::before { + content: "\f0ed"; /* http://fontawesome.io/icon/cloud-download/ */ +} + #form { background: #eee; border-top: 1px solid #ddd; @@ -2055,7 +2116,6 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */ #windows .header .topic, #settings .error, #help .help-item, - #help .about, #loading, #context-menu, #form #input, diff --git a/client/index.html b/client/index.html index 3c3b253e..447366d5 100644 --- a/client/index.html +++ b/client/index.html @@ -85,6 +85,7 @@
+
diff --git a/client/js/socket-events/changelog.js b/client/js/socket-events/changelog.js new file mode 100644 index 00000000..7d32ffb3 --- /dev/null +++ b/client/js/socket-events/changelog.js @@ -0,0 +1,9 @@ +"use strict"; + +const $ = require("jquery"); +const socket = require("../socket"); +const templates = require("../../views"); + +socket.on("changelog", function(data) { + $("#changelog").html(templates.windows.changelog(data)); +}); diff --git a/client/js/socket-events/configuration.js b/client/js/socket-events/configuration.js index fd687a7b..cd2489a0 100644 --- a/client/js/socket-events/configuration.js +++ b/client/js/socket-events/configuration.js @@ -14,6 +14,7 @@ socket.on("configuration", function(data) { $("#settings").html(templates.windows.settings(data)); $("#connect").html(templates.windows.connect(data)); $("#help").html(templates.windows.help(data)); + $("#changelog").html(templates.windows.changelog()); $("#play").on("click", () => { const pop = new Audio(); @@ -65,4 +66,22 @@ socket.on("configuration", function(data) { // Store the "previous" value, for next time $(this).data("lastvalue", nick); }); + + $("#view-changelog").on("click", function() { + $("#windows > .active") + .removeClass("active") + .find(".chat") + .unsticky(); + + $("#changelog") + .addClass("active"); + + history.pushState({ + clickTarget: "#view-changelog", + }, null, "#changelog"); + + return false; + }).one("click", function() { + socket.emit("changelog"); + }); }); diff --git a/client/js/socket-events/index.js b/client/js/socket-events/index.js index f14c670a..0841459e 100644 --- a/client/js/socket-events/index.js +++ b/client/js/socket-events/index.js @@ -19,3 +19,4 @@ require("./users"); require("./sign_out"); require("./sessions_list"); require("./configuration"); +require("./changelog"); diff --git a/client/views/index.js b/client/views/index.js index 3ed35fba..0bba75d8 100644 --- a/client/views/index.js +++ b/client/views/index.js @@ -26,6 +26,7 @@ module.exports = { settings: require("./windows/settings.tpl"), connect: require("./windows/connect.tpl"), help: require("./windows/help.tpl"), + changelog: require("./windows/changelog.tpl"), }, chan: require("./chan.tpl"), diff --git a/client/views/windows/changelog.tpl b/client/views/windows/changelog.tpl new file mode 100644 index 00000000..668a62ec --- /dev/null +++ b/client/views/windows/changelog.tpl @@ -0,0 +1,29 @@ +
+ +
+
+ {{#if current}} + {{#if latest}} + + The Lounge {{latest.version}}{{#if latest.prerelease}} (pre-release){{/if}} is now available. + Click to view details on GitHub. + + {{else if current.changelog}} +
+ The Lounge is up to date! +
+ {{/if}} + +

Release notes for {{current.version}}

+ + {{#if current.changelog}} +

Introduction

+
{{{current.changelog}}}
+ {{else}} +

Unable to retrieve releases from GitHub.

+

View release notes for this version on GitHub

+ {{/if}} + {{else}} +

Loading changelog…

+ {{/if}} +
diff --git a/client/views/windows/help.tpl b/client/views/windows/help.tpl index 35ef3ede..86f7d25c 100644 --- a/client/views/windows/help.tpl +++ b/client/views/windows/help.tpl @@ -4,6 +4,28 @@

Help

+

About The Lounge

+ +
+ {{#if gitCommit}} +

The Lounge is running from source (commit {{gitCommit}}) based on {{version}}

+

Compare changes between {{gitCommit}} and master to see what you are missing

+

Compare changes between {{version}} and {{gitCommit}} to see the changes made

+ {{else}} +

The Lounge is running {{version}}.

+ {{/if}} + + {{#unless public}} + + {{/unless}} + +

+ View website
+ View documentation
+ Report a bug on GitHub +

+
+

Keyboard Shortcuts

@@ -11,7 +33,7 @@ Ctrl + /
-

Switch to the previous/next window in the channel list

+

Switch to the previous/next window in the channel list.

@@ -481,20 +503,4 @@

- -

About The Lounge

- -

- {{#if gitCommit}} - The Lounge is running from source - ({{ gitCommit }}).
- {{else}} - The Lounge is in version {{version}} - (See release notes).
- {{/if}} - - Website
- Documentation
- Report a bug -

diff --git a/src/plugins/changelog.js b/src/plugins/changelog.js new file mode 100644 index 00000000..f5fc2c1f --- /dev/null +++ b/src/plugins/changelog.js @@ -0,0 +1,65 @@ +"use strict"; + +const pkg = require("../../package.json"); +const request = require("request"); + +module.exports = { + sendChangelog: handleChangelog, +}; + +function handleChangelog(callback) { + const changelog = { + current: { + version: `v${pkg.version}`, + }, + }; + + request.get({ + uri: "https://api.github.com/repos/thelounge/lounge/releases", + headers: { + Accept: "application/vnd.github.v3.html", // Request rendered markdown + "User-Agent": pkg.name + "; +" + pkg.repository.git, // Identify the client + }, + }, (error, response, body) => { + if (error || response.statusCode !== 200) { + callback(changelog); + + return; + } + + let i = 0; + let release; + let prerelease = false; + + body = JSON.parse(body); + + for (i = 0; i < body.length; i++) { + release = body[i]; + if (release.tag_name === changelog.current.version) { + changelog.current.changelog = release.body_html; + prerelease = release.prerelease; + + break; + } + } + + if (i > 0 && changelog.current) { + for (i = 0; i < body.length; i++) { + release = body[i]; + + // Find latest release or pre-release if current version is also a pre-release + if (!release.prerelease || release.prerelease === prerelease) { + changelog.latest = { + prerelease: release.prerelease, + version: release.tag_name, + url: release.html_url, + }; + + break; + } + } + } + + callback(changelog); + }); +} diff --git a/src/server.js b/src/server.js index 9d719d08..aaec0dfc 100644 --- a/src/server.js +++ b/src/server.js @@ -14,6 +14,7 @@ var colors = require("colors/safe"); const net = require("net"); const Identification = require("./identification"); const themes = require("./plugins/themes"); +const changelog = require("./plugins/changelog"); // The order defined the priority: the first available plugin is used // ALways keep local auth in the end, which should always be enabled. @@ -340,6 +341,14 @@ function initializeClient(socket, client, token, lastMessage) { } ); + if (!Helper.config.public) { + socket.on("changelog", function() { + changelog.sendChangelog((data) => { + socket.emit("changelog", data); + }); + }); + } + socket.on("msg:preview:toggle", function(data) { const networkAndChan = client.find(data.target); if (!networkAndChan) {