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:
parent
2361833844
commit
d3ce64374d
@ -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);
|
||||
},
|
||||
};
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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, {
|
||||
|
||||
@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user