diff --git a/app/assets/javascripts/discourse/app/components/software-update-prompt.gjs b/app/assets/javascripts/discourse/app/components/software-update-prompt.gjs
new file mode 100644
index 00000000000..8c29bdc965d
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/software-update-prompt.gjs
@@ -0,0 +1,117 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
+import { cancel } from "@ember/runloop";
+import { service } from "@ember/service";
+import DButton from "discourse/components/d-button";
+import concatClass from "discourse/helpers/concat-class";
+import { isTesting } from "discourse-common/config/environment";
+import i18n from "discourse-common/helpers/i18n";
+import discourseLater from "discourse-common/lib/later";
+import { bind } from "discourse-common/utils/decorators";
+
+export default class SoftwareUpdatePrompt extends Component {
+ @service messageBus;
+ @service session;
+
+ @tracked showPrompt = false;
+ @tracked animatePrompt = false;
+ timeoutHandler;
+
+ constructor() {
+ super(...arguments);
+
+ this.messageBus.subscribe("/refresh_client", this.onRefresh);
+ this.messageBus.subscribe("/global/asset-version", this.onAsset);
+ }
+
+ willDestroy() {
+ super.willDestroy(...arguments);
+
+ this.messageBus.unsubscribe("/refresh_client", this.onRefresh);
+ this.messageBus.unsubscribe("/global/asset-version", this.onAsset);
+
+ cancel(this.timeoutHandler);
+ }
+
+ @bind
+ onRefresh() {
+ this.session.requiresRefresh = true;
+ }
+
+ @bind
+ onAsset(version) {
+ if (this.session.assetVersion !== version) {
+ this.session.requiresRefresh = true;
+ }
+
+ if (!this.timeoutHandler && this.session.requiresRefresh) {
+ if (isTesting()) {
+ this.updatePromptState(true);
+ } else {
+ // Since we can do this transparently for people browsing the forum
+ // hold back the message 24 hours.
+ this.timeoutHandler = discourseLater(
+ () => this.updatePromptState(true),
+ 1000 * 60 * 24 * 60
+ );
+ }
+ }
+ }
+
+ updatePromptState(value) {
+ // when adding the message, we inject the HTML then add the animation
+ // when dismissing, things need to happen in the opposite order
+ const firstProp = value ? "showPrompt" : "animatePrompt";
+ const secondProp = value ? "animatePrompt" : "showPrompt";
+
+ this[firstProp] = value;
+
+ if (isTesting()) {
+ this[secondProp] = value;
+ } else {
+ discourseLater(() => (this[secondProp] = value), 500);
+ }
+ }
+
+ @action
+ refreshPage() {
+ document.location.reload();
+ }
+
+ @action
+ dismiss() {
+ this.updatePromptState(false);
+ }
+
+
+ {{#if this.showPrompt}}
+
+ {{/if}}
+
+}
diff --git a/app/assets/javascripts/discourse/app/components/software-update-prompt.hbs b/app/assets/javascripts/discourse/app/components/software-update-prompt.hbs
deleted file mode 100644
index 7e5d4af96e3..00000000000
--- a/app/assets/javascripts/discourse/app/components/software-update-prompt.hbs
+++ /dev/null
@@ -1,24 +0,0 @@
-{{#if this.showPrompt}}
-
-
-
- {{d-icon "redo"}}
- {{html-safe (i18n "software_update_prompt.message")}}
- {{d-icon "times"}}
-
-
-
-{{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/software-update-prompt.js b/app/assets/javascripts/discourse/app/components/software-update-prompt.js
deleted file mode 100644
index 8d3ec944da6..00000000000
--- a/app/assets/javascripts/discourse/app/components/software-update-prompt.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import Component from "@ember/component";
-import { action } from "@ember/object";
-import { cancel } from "@ember/runloop";
-import { isTesting } from "discourse-common/config/environment";
-import getURL from "discourse-common/lib/get-url";
-import discourseLater from "discourse-common/lib/later";
-import discourseComputed, { bind, on } from "discourse-common/utils/decorators";
-
-export default Component.extend({
- tagName: "",
-
- showPrompt: false,
- animatePrompt: false,
- _timeoutHandler: null,
-
- init() {
- this._super(...arguments);
-
- this.messageBus.subscribe("/refresh_client", this.onRefresh);
- this.messageBus.subscribe("/global/asset-version", this.onAsset);
- },
-
- willDestroy() {
- this._super(...arguments);
-
- this.messageBus.unsubscribe("/refresh_client", this.onRefresh);
- this.messageBus.unsubscribe("/global/asset-version", this.onAsset);
- },
-
- @bind
- onRefresh() {
- this.session.requiresRefresh = true;
- },
-
- @bind
- onAsset(version) {
- if (this.session.assetVersion !== version) {
- this.session.requiresRefresh = true;
- }
-
- if (!this._timeoutHandler && this.session.requiresRefresh) {
- if (isTesting()) {
- this.updatePromptState(true);
- } else {
- // Since we can do this transparently for people browsing the forum
- // hold back the message 24 hours.
- this._timeoutHandler = discourseLater(() => {
- this.updatePromptState(true);
- }, 1000 * 60 * 24 * 60);
- }
- }
- },
-
- @discourseComputed
- rootUrl() {
- return getURL("/");
- },
-
- updatePromptState(value) {
- // when adding the message, we inject the HTML then add the animation
- // when dismissing, things need to happen in the opposite order
- const firstProp = value ? "showPrompt" : "animatePrompt",
- secondProp = value ? "animatePrompt" : "showPrompt";
-
- this.set(firstProp, value);
- if (isTesting()) {
- this.set(secondProp, value);
- } else {
- discourseLater(() => {
- this.set(secondProp, value);
- }, 500);
- }
- },
-
- @action
- refreshPage() {
- document.location.reload();
- },
-
- @action
- dismiss() {
- this.updatePromptState(false);
- },
-
- @on("willDestroyElement")
- _resetTimeoutHandler() {
- this._timeoutHandler && cancel(this._timeoutHandler);
- this._timeoutHandler = null;
- },
-});
diff --git a/app/assets/stylesheets/common/software-update-prompt.scss b/app/assets/stylesheets/common/software-update-prompt.scss
index 3fb47e6ee85..fe3e28049b0 100644
--- a/app/assets/stylesheets/common/software-update-prompt.scss
+++ b/app/assets/stylesheets/common/software-update-prompt.scss
@@ -5,7 +5,6 @@
left: 0;
top: var(--header-offset, 60px);
background-color: var(--tertiary-low);
- color: var(--tertiary);
max-height: 0;
overflow: hidden;
transition: max-height 0.3s;
@@ -20,15 +19,15 @@
}
.update-prompt-message {
- cursor: pointer;
+ color: var(--tertiary);
padding: 0.75em 0;
.d-icon {
- margin-right: 0.33em;
+ color: var(--tertiary);
font-size: 0.9em;
}
- span {
+ .d-button-label > span {
text-decoration: underline;
}
}
@@ -39,16 +38,8 @@
height: 44px;
flex: 1;
- span {
- cursor: pointer;
- height: 100%;
- display: flex;
- align-items: center;
- padding-left: 20px;
-
- &:hover {
- color: var(--tertiary-hover);
- }
+ .d-icon {
+ color: var(--tertiary);
}
}