DEV: Move mobile view logic to Site service

Deprecates `discourse/lib/mobile` import.

Also refactors the mobile view info logic (removes jQuery, uses `URL` and `URLSearchParams` classes)
This commit is contained in:
Jarek Radosz 2022-08-14 11:32:23 +02:00
parent 2361833844
commit d3ce64374d
No known key found for this signature in database
GPG Key ID: 62D0FBAE5BF9B953
5 changed files with 84 additions and 63 deletions

View File

@ -1,21 +1,15 @@
import Mobile from "discourse/lib/mobile";
import { setResolverOption } from "discourse-common/resolver";
import { setResolverOption as setLegacyResolverOption } from "discourse-common/lib/legacy-resolver";
// Initializes the `Mobile` helper object.
// Initializes the `mobileView` resolver option
export default {
name: "mobile",
after: "inject-objects",
initialize(container) {
Mobile.init();
const site = container.lookup("service:site");
site.set("mobileView", Mobile.mobileView);
site.set("desktopView", !Mobile.mobileView);
site.set("isMobileDevice", Mobile.isMobileDevice);
setResolverOption("mobileView", Mobile.mobileView);
setLegacyResolverOption("mobileView", Mobile.mobileView);
setResolverOption("mobileView", site.mobileView);
setLegacyResolverOption("mobileView", site.mobileView);
},
};

View File

@ -1,6 +1,5 @@
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Mobile from "discourse/lib/mobile";
import { bind } from "discourse-common/utils/decorators";
import showModal from "discourse/lib/show-modal";
import I18n from "I18n";
@ -117,7 +116,7 @@ export default class CodeblockButtons {
if (
this.showFullscreen &&
!Mobile.isMobileDevice &&
!this.site.isMobileDevice &&
codeBlock.scrollWidth > codeBlock.clientWidth
) {
const fullscreenButton = document.createElement("button");

View File

@ -1,67 +1,35 @@
import { isTesting } from "discourse-common/config/environment";
import { getOwner } from "discourse-common/lib/get-owner";
import deprecated from "discourse-common/lib/deprecated";
let mobileForced = false;
deprecated(
"`discourse/lib/mobile` import is deprecated. Use `isMobileDevice`, `mobileView`, `forceMobile` properties and `toggleMobileView` method on `site:service`"
);
function site() {
// Use the "default owner"
return getOwner().lookup("site:service");
}
// An object that is responsible for logic related to mobile devices.
const Mobile = {
isMobileDevice: false,
mobileView: false,
get isMobileDevice() {
return site().isMobileDevice;
},
init() {
const $html = $("html");
this.isMobileDevice = mobileForced || $html.hasClass("mobile-device");
this.mobileView = mobileForced || $html.hasClass("mobile-view");
if (isTesting() || mobileForced) {
return;
}
try {
if (window.location.search.match(/mobile_view=1/)) {
localStorage.mobileView = true;
}
if (window.location.search.match(/mobile_view=0/)) {
localStorage.mobileView = false;
}
if (window.location.search.match(/mobile_view=auto/)) {
localStorage.removeItem("mobileView");
}
if (localStorage.mobileView) {
let savedValue = localStorage.mobileView === "true";
if (savedValue !== this.mobileView) {
this.reloadPage(savedValue);
}
}
} catch (err) {
// localStorage may be disabled, just skip this
// you get security errors if it is disabled
}
get mobileView() {
return site().mobileView;
},
toggleMobileView() {
try {
if (localStorage) {
localStorage.mobileView = !this.mobileView;
}
} catch (err) {
// localStorage may be disabled, skip
}
this.reloadPage(!this.mobileView);
},
reloadPage(mobile) {
window.location.assign(
window.location.pathname + "?mobile_view=" + (mobile ? "1" : "0")
);
return site().toggleMobileView();
},
};
export function forceMobile() {
mobileForced = true;
site().forceMobile = true;
}
export function resetMobile() {
mobileForced = false;
site().forceMobile = false;
}
export default Mobile;

View File

@ -11,14 +11,21 @@ import discourseComputed from "discourse-common/utils/decorators";
import { getOwner } from "discourse-common/lib/get-owner";
import { isEmpty } from "@ember/utils";
import { htmlSafe } from "@ember/template";
import { isTesting } from "discourse-common/config/environment";
import DiscourseURL from "discourse/lib/url";
const Site = RestModel.extend({
isReadOnly: alias("is_readonly"),
mobileForced: false,
isMobileDevice: false,
mobileView: false,
desktopView: true,
init() {
this._super(...arguments);
this.topicCountDesc = ["topic_count:desc"];
this._initializeMobileViewInfo();
},
@discourseComputed("notification_types")
@ -139,6 +146,60 @@ const Site = RestModel.extend({
return newCategory;
}
},
toggleMobileView() {
try {
if (localStorage) {
localStorage.mobileView = !this.mobileView;
}
} catch (err) {
// localStorage may be disabled, skip
}
const url = new URL(document.location);
url.searchParams.set("mobile_view", this.mobileView ? "0" : "1");
DiscourseURL.redirectAbsolute(url.toString());
},
_initializeMobileViewInfo() {
const { classList } = document.documentElement;
this.isMobileDevice =
this.mobileForced || classList.contains("mobile-device");
this.mobileView = this.mobileForced || classList.contains("mobile-view");
this.desktopView = !this.mobileView;
if (isTesting() || this.mobileForced) {
return;
}
const url = new URL(document.location);
try {
switch (url.searchParams.get("mobile_view")) {
case "1":
localStorage.mobileView = true;
break;
case "0":
localStorage.mobileView = false;
break;
case "auto":
localStorage.removeItem("mobileView");
break;
}
if (localStorage.mobileView) {
const savedValue = localStorage.mobileView === "true";
if (savedValue !== this.mobileView) {
url.searchParams.set("mobile_view", savedValue ? "1" : "0");
DiscourseURL.redirectAbsolute(url.toString());
}
}
} catch (err) {
// localStorage may be disabled, just skip this
// you get security errors if it is disabled
}
},
});
Site.reopenClass(Singleton, {

View File

@ -10,7 +10,6 @@ import { findAll } from "discourse/models/login-method";
import { getOwner } from "discourse-common/lib/get-owner";
import getURL from "discourse-common/lib/get-url";
import logout from "discourse/lib/logout";
import mobile from "discourse/lib/mobile";
import { inject as service } from "@ember/service";
import { setting } from "discourse/lib/computed";
import showModal from "discourse/lib/show-modal";
@ -48,7 +47,7 @@ const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
},
toggleMobileView() {
mobile.toggleMobileView();
this.site.toggleMobileView();
},
toggleSidebar() {