Compare commits

...
This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.

4 Commits

Author SHA1 Message Date
Jarek Radosz
b29dc2971c
fixies 2022-08-14 22:38:04 +02:00
Jarek Radosz
20299450c7
Clean up 2022-08-14 21:16:47 +02:00
Jarek Radosz
4665ad3dd7
Merge branch 'main' into a-move-mobile 2022-08-14 21:15:04 +02:00
Jarek Radosz
d3ce64374d
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)
2022-08-14 11:32:23 +02:00
6 changed files with 55 additions and 73 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,31 @@
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`, properties and `toggleMobileView` method on `service:site`."
);
function site() {
// Use the "default owner"
return getOwner().lookup("service:site");
}
// 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;
}
export function resetMobile() {
mobileForced = false;
site().mobileView = true;
}
export default Mobile;

View File

@ -11,8 +11,10 @@ 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 DiscourseURL from "discourse/lib/url";
const Site = RestModel.extend({
_mobileOverride: null,
isReadOnly: alias("is_readonly"),
init() {
@ -139,6 +141,30 @@ const Site = RestModel.extend({
return newCategory;
}
},
toggleMobileView() {
const url = new URL(document.location);
url.searchParams.set("mobile_view", this.mobileView ? "0" : "1");
DiscourseURL.redirectAbsolute(url.toString());
},
get isMobileDevice() {
const { classList } = document.documentElement;
return this._mobileOverride ?? classList.contains("mobile-device");
},
get mobileView() {
const { classList } = document.documentElement;
return this._mobileOverride ?? classList.contains("mobile-view");
},
set mobileView(value) {
return (this._mobileOverride = value);
},
get desktopView() {
return !this.mobileView;
},
});
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() {

View File

@ -10,7 +10,6 @@ import {
currentSettings,
mergeSettings,
} from "discourse/tests/helpers/site-settings";
import { forceMobile, resetMobile } from "discourse/lib/mobile";
import { getApplication, getContext, settled } from "@ember/test-helpers";
import { getOwner } from "discourse-common/lib/get-owner";
import { run } from "@ember/runloop";
@ -292,12 +291,7 @@ export function acceptance(name, optionsOrCallback) {
const setup = {
beforeEach() {
resetMobile();
resetExtraClasses();
if (mobileView) {
forceMobile();
}
if (loggedIn) {
logIn();
@ -314,6 +308,11 @@ export function acceptance(name, optionsOrCallback) {
}
this.siteSettings = currentSettings();
if (mobileView) {
siteChanges ||= {};
siteChanges.mobileView = true;
}
resetSite(currentSettings(), siteChanges);
this.container = getOwner(this);
@ -328,12 +327,13 @@ export function acceptance(name, optionsOrCallback) {
},
afterEach() {
resetMobile();
let app = getApplication();
options?.afterEach?.call(this);
if (loggedIn) {
User.current().stopTrackingStatus();
}
testCleanup(this.container, app);
// We do this after reset so that the willClearRender will have already fired