= AppCompatActivityContext;
-
public constructor(props: P | Readonly) {
super(props);
this.onlyAndroid();
+ window["onBackButton"] = new Event("onBackButton");
+
this.onCreate = this.onCreate.bind(this);
this.onCreateToolbar = this.onCreateToolbar.bind(this);
}
+ public onBackButton(): void {}
+
private onlyAndroid(): void {
os.setStatusBarColor(this.setStatusbarColor(), false);
if (SharedPreferences.getBoolean("enableBottomTabs_switch", false)) {
@@ -42,6 +40,7 @@ class AppCompatActivity
extends ActivityX
{
public style: CSSProperties = {};
public componentDidMount(): void {
+ os.addNativeEventListener("onBackButton", this.onBackButton);
this.onlyAndroid();
}
@@ -49,7 +48,9 @@ class AppCompatActivity
extends ActivityX
{
this.onlyAndroid();
}
- public componentWillUnmount(): void {}
+ public componentWillUnmount(): void {
+ os.removeNativeEventListener("onBackButton", this.onBackButton);
+ }
/**
* Sets an custom status bar color for the activity
@@ -62,10 +63,42 @@ class AppCompatActivity
extends ActivityX
{
}
}
+ /**
+ * Creates the activity
+ */
+ public onCreate(): JSX.Element {
+ return <>>;
+ }
+
+ public onCreateModal(): JSX.Element {
+ return <>>;
+ }
+
+ public onCreateBottomToolbar(): JSX.Element {
+ return <>>;
+ }
+
+ public onCreateFAB(): JSX.Element {
+ return <>>;
+ }
+
+ public onInit(): void {}
+
+ public onShow(): void {}
+
+ public onHide(): void {}
+
+ public onInfiniteScroll(): void {}
+
+ //@ts-ignore
+ public get pageModifier(): string {
+ return "";
+ }
+
/**
* Renders the Toolbar
*/
- public onCreateToolbar(): Toolbar.Props | any {
+ public onCreateToolbar() {
return {
title: "Default",
};
@@ -73,27 +106,24 @@ class AppCompatActivity
extends ActivityX
{
public render = (): JSX.Element => {
return (
-
-
- {
- return ;
- }}
- >
-
-
-
-
-
-
+
+ {
+ return ;
+ }}
+ >
+
+
+
);
};
}
diff --git a/Website/src/activitys/MainActivity.tsx b/Website/src/activitys/MainActivity.tsx
index d17ddf68e..bb9e1b688 100644
--- a/Website/src/activitys/MainActivity.tsx
+++ b/Website/src/activitys/MainActivity.tsx
@@ -1,11 +1,10 @@
import { Component } from "react";
-import { RouterUtil } from "react-onsenui";
-import { Page, RouterNavigator } from "react-onsenui";
+import { Page, RouterNavigator, RouterUtil } from "react-onsenui";
import MainApplication from "@Activitys/MainApplication";
-import Constants from "@Native/Constants";
import NoRootActivity from "./NoRootActivity";
-import Shell from "@Native/ShellBuilder";
+import Shell from "@Native/Shell";
import { link } from "googlers-tools";
+import { os } from "@Native/os";
interface ModuleOptions {
verified?: boolean;
@@ -39,7 +38,7 @@ class MainActivity extends Component {
super(props);
const CheckRoot = () => {
- if (Constants.isAndroid) {
+ if (os.isAndroid) {
if (Shell.isAppGrantedRoot()) {
return MainApplication;
} else {
diff --git a/Website/src/activitys/MainApplication.tsx b/Website/src/activitys/MainApplication.tsx
index 13ab9b13a..f69d89abf 100644
--- a/Website/src/activitys/MainApplication.tsx
+++ b/Website/src/activitys/MainApplication.tsx
@@ -1,14 +1,16 @@
-import Toolbar from "@Builders/ToolbarBuilder";
+import Icon from "@Components/Icon";
+import { TabWrapper } from "@Components/TabWrapper";
import { SettingsRounded } from "@mui/icons-material";
import { os } from "@Native/os";
import SharedPreferences from "@Native/SharedPreferences";
-import Toast from "@Native/Toast";
import { string } from "@Strings";
+import Constants from "@Utils/Constants";
+import { Disappear } from "react-disappear";
import { Tab, Tabbar, TabbarRenderTab, ToolbarButton } from "react-onsenui";
-import { ActivityXRenderData } from "react-onsenuix";
import AppCompatActivity from "./AppCompatActivity";
import DeviceModuleFragment from "./fragments/DeviceModuleFragment";
import ExploreModuleFragment from "./fragments/ExploreModuleFragment";
+import RepoActivity from "./RepoActivity";
import SettingsActivity from "./SettingsActivity";
interface Props {
@@ -29,29 +31,39 @@ interface Props {
pushPage: any;
}
-class MainApplication extends AppCompatActivity {
+interface States {
+ toolbarShadow: string;
+ toolbarTitle: string;
+}
+
+class MainApplication extends AppCompatActivity {
public constructor(props: Props | Readonly) {
super(props);
- this.state = {};
+ this.state = {
+ toolbarShadow: "noshadow",
+ toolbarTitle: "",
+ };
this.openSettings = this.openSettings.bind(this);
this.renderTabs = this.renderTabs.bind(this);
+ this.onCreateFAB = this.onCreateFAB.bind(this);
}
- public onCreateToolbar(): Toolbar.Props {
+ public onCreateToolbar() {
return {
- title: "Magisk Module Repo Loader",
+ modifier: this.state.toolbarShadow,
+ title: os.isAndroid ? Constants.GlobalMMRLTitle : this.state.toolbarTitle,
addToolbarButtonPosition: "right",
addToolbarButton: (
-
+
),
};
}
- public componentDidMount() {
- super.componentDidMount;
+ public onBackButton(): void {
+ os.close();
}
public componentDidUpdate() {
@@ -68,17 +80,17 @@ class MainApplication extends AppCompatActivity {
private renderTabs(): TabbarRenderTab[] {
return [
{
- content: ,
+ content: ,
tab: ,
},
{
- content: ,
+ content: ,
tab: ,
},
];
}
- public onCreate(data: ActivityXRenderData) {
+ public onCreate() {
return (
<>
{os.isAndroid ? (
@@ -88,7 +100,34 @@ class MainApplication extends AppCompatActivity {
renderTabs={this.renderTabs}
/>
) : (
-
+ <>
+ {
+ this.setState({ toolbarShadow: visible ? "noshadow" : "" });
+ }}
+ >
+
+ {
+ this.setState({ toolbarTitle: visible ? "" : Constants.GlobalMMRLTitle });
+ }}
+ >
+ {Constants.GlobalMMRLTitle}
+
+
+
+
+ >
)}
>
);
diff --git a/Website/src/activitys/NoRootActivity.tsx b/Website/src/activitys/NoRootActivity.tsx
index 036693cc6..1d16b0f37 100644
--- a/Website/src/activitys/NoRootActivity.tsx
+++ b/Website/src/activitys/NoRootActivity.tsx
@@ -1,15 +1,15 @@
-import { Button, Card } from "react-onsenuix";
import AppCompatActivity from "./AppCompatActivity";
import Toast from "@Native/Toast";
-import Toolbar from "@Builders/ToolbarBuilder";
+import { string } from "@Strings";
+import { Button, Card } from "react-onsenui";
class NoRootActivity extends AppCompatActivity {
private readonly magiskPackageName: string = "com.topjohnwu.magisk";
private readonly magiskDeltaPackageName: string = "io.github.huskydg.magisk";
- public onCreateToolbar(): Toolbar.Props {
+ public onCreateToolbar() {
return {
- title: "No Root",
+ title: string.no_root,
};
}
@@ -17,14 +17,12 @@ class NoRootActivity extends AppCompatActivity {
return (
- Failed!
-
- It seems that this device has no root? Please check the Magisk app and enable root permission. If you don't have root, then
- search in the internet for your device.
-
+ {string.failed}!
+ {string.no_root_message}
{
if (nos.isPackageInstalled(this.magiskPackageName)) {
nos.launchAppByPackageName(this.magiskPackageName);
@@ -35,7 +33,7 @@ class NoRootActivity extends AppCompatActivity {
}
}}
>
- Open Magisk
+ {string.open_magisk}
);
diff --git a/Website/src/activitys/RepoActivity.tsx b/Website/src/activitys/RepoActivity.tsx
new file mode 100644
index 000000000..419b64ab2
--- /dev/null
+++ b/Website/src/activitys/RepoActivity.tsx
@@ -0,0 +1,418 @@
+import AppCompatActivity from "./AppCompatActivity";
+import SharedPreferences, { ISharedPreferences } from "@Native/SharedPreferences";
+import {
+ Add,
+ DeleteRounded,
+ ExtensionRounded,
+ LanguageRounded,
+ SupportRounded,
+ UploadFileRounded,
+ VolunteerActivismRounded,
+} from "@mui/icons-material";
+import { link, util } from "googlers-tools";
+import ons from "onsenui";
+import Icon from "@Components/Icon";
+import { AlertDialog as Dialog, Input, List, ListHeader, ListItem, Switch, ToolbarButton } from "react-onsenui";
+import Toast from "@Native/Toast";
+import { os } from "@Native/os";
+import { OverridableComponent } from "@mui/material/OverridableComponent";
+import { SvgIconTypeMap } from "@mui/material/SvgIcon/SvgIcon";
+import axios from "axios";
+import { string } from "@Strings";
+import { Fragment } from "react";
+import { Searchbar } from "@Components/Searchbar";
+import AlertDialog from "@Builders/AlertDialog";
+
+interface Props {
+ pushPage: any;
+ popPage: any;
+}
+
+interface States {
+ repos: Array;
+ alertDialogShown: boolean;
+ repoName: string;
+ repoLink: string;
+ searchValue: string;
+ finalSearchValue: string;
+}
+
+interface ListItemProps {
+ part: any;
+ text: string;
+ icon: OverridableComponent>;
+ onClick: () => void;
+}
+
+export interface RepoInterface {
+ /**
+ * An required filed, to disply the repository name
+ */
+ name: string;
+ /**
+ * An given website link for the repository
+ */
+ website?: string | undefined;
+ /**
+ * Given support link i.g. Telegram, Xda, GitHub or something
+ */
+ support?: string | undefined;
+ donate?: string | undefined;
+ submitModule?: string | undefined;
+ last_update?: string | number | undefined;
+ modules: string;
+ /**
+ * The setting enabled by default if the repo is built-in
+ */
+ readonly: boolean;
+ isOn: boolean;
+ built_in_type?: string;
+}
+
+class RepoActivity extends AppCompatActivity {
+ private pref: ISharedPreferences;
+
+ private readonly MAX_REPO_LENGTH: number = 5;
+
+ public constructor(props: Props | Readonly) {
+ super(props);
+
+ this.pref = new SharedPreferences();
+
+ this.state = {
+ repos: JSON.parse(this.pref.getString("repos", "[]")),
+ alertDialogShown: false,
+ repoName: "",
+ repoLink: "",
+ searchValue: "",
+ finalSearchValue: "",
+ };
+
+ this.addRepo = this.addRepo.bind(this);
+ this.removeRepo = this.removeRepo.bind(this);
+ this.changeEnabledState = this.changeEnabledState.bind(this);
+ this.onCreateToolbar = this.onCreateToolbar.bind(this);
+
+ this.hideAlertDialog = this.hideAlertDialog.bind(this);
+ this.showAlertDialog = this.showAlertDialog.bind(this);
+ this.handleRepoLinkChange = this.handleRepoLinkChange.bind(this);
+ this.handleRepoNameChange = this.handleRepoNameChange.bind(this);
+ this.repoSearchFilter = this.repoSearchFilter.bind(this);
+ this.triggerRepoSearch = this.triggerRepoSearch.bind(this);
+ }
+
+ // Contact @Der_Googler on Telegram to request changes
+ public static getReadOnlyRepos(): Array {
+ return [
+ {
+ name: "Magisk Modules Alternative Repository",
+ website: "https://github.com/Magisk-Modules-Alt-Repo",
+ support: undefined,
+ donate: undefined,
+ submitModule: "https://github.com/Magisk-Modules-Alt-Repo/submission",
+ last_update: undefined,
+ modules: "https://raw.githubusercontent.com/Magisk-Modules-Alt-Repo/json/main/modules.json",
+ readonly: true,
+ isOn: SharedPreferences.getBoolean("repoMMARenabled", true),
+ built_in_type: "MMAR",
+ },
+ {
+ name: "Googlers Magisk Repo",
+ website: "https://github.com/Googlers-Magisk-Repo",
+ support: undefined,
+ donate: undefined,
+ submitModule: undefined,
+ last_update: undefined,
+ modules: "https://repo.dergoogler.com/modules.json",
+ readonly: true,
+ isOn: SharedPreferences.getBoolean("repoGMRenabled", true),
+ built_in_type: "GMR",
+ },
+ ];
+ }
+
+ public componentDidMount(): void {
+ const _: string = "userAcceptNewRepos";
+ const userAcceptNewRepos = SharedPreferences.getBoolean(_, false);
+
+ if (!userAcceptNewRepos) {
+ const builder = AlertDialog.Builder;
+ builder.setTitle("Custom repositories!");
+ builder.setMessage(
+
+ MMRL introduces new repositories system with 1.4.2 . Now can you load every repo into MMRL (This can slow
+ down the app if to much repo at once are enabled)
+
+ Magisk Modules Alternative Repository is an read-only repo and can't be removed.
+
+
+ );
+ builder.setPositiveButton("Oaky!", () => {
+ SharedPreferences.setBoolean(_, true);
+ });
+ builder.setCancelable(true);
+ builder.show();
+ }
+ }
+
+ private getRepos(): Array {
+ return this.pref.getJSON>("repos", []);
+ }
+
+ private removeRepo(item: any) {
+ let array = this.getRepos();
+
+ var index = array.indexOf(item);
+ array.splice(index, 1);
+
+ this.pref.setJSON>("repos", array);
+ this.setState({ repos: this.getRepos() });
+ }
+
+ private changeEnabledState(state: any) {
+ let array = this.getRepos();
+ var item = array.find((item: RepoInterface) => item.isOn === !state);
+ if (item) {
+ item.isOn = state;
+ }
+ this.pref.setJSON>("repos", array);
+ }
+
+ private addRepo() {
+ const { repoName, repoLink } = this.state;
+
+ if (repoName != "") {
+ if (link.validURL(repoLink)) {
+ axios
+ .get(repoLink)
+ .then((response) => {
+ const data = response.data;
+ this.pref.setJSON>("repos", [
+ ...this.pref.getJSON>("repos", []),
+ {
+ name: repoName,
+ website: util.typeCheck(link.validURL(data.website), null),
+ support: util.typeCheck(link.validURL(data.support), null),
+ donate: util.typeCheck(link.validURL(data.donate), null),
+ submitModule: util.typeCheck(link.validURL(data.submitModule), null),
+ last_update: util.typeCheck(link.validURL(data.last_update), null),
+ modules: repoLink,
+ readonly: false,
+ isOn: false,
+ },
+ ]);
+
+ this.hideAlertDialog();
+ })
+ .catch((error) => {
+ Toast.makeText(error, Toast.LENGTH_SHORT).show();
+ this.hideAlertDialog();
+ })
+ .then(() => {
+ this.setState({ repos: this.getRepos(), repoName: "", repoLink: "" });
+ });
+ } else {
+ Toast.makeText("The given link isn't valid.", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText("Can't add nameless repo.", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public onCreateToolbar() {
+ return {
+ title: "Repos",
+ onBackButton: this.props.popPage,
+ addToolbarButtonPosition: "right",
+ addToolbarButton: (
+
+
+
+ ),
+ };
+ }
+
+ private showAlertDialog() {
+ if (this.getRepos().length === this.MAX_REPO_LENGTH) {
+ Toast.makeText("You can't add more than 5 repositories (Read-Only Repos are not counted).", Toast.LENGTH_SHORT).show();
+ } else {
+ this.setState({ alertDialogShown: true });
+ }
+ }
+
+ private hideAlertDialog() {
+ this.setState({ alertDialogShown: false });
+ }
+
+ private handleRepoNameChange(e: any) {
+ this.setState({ repoName: e.target.value });
+ }
+ private handleRepoLinkChange(e: any) {
+ this.setState({ repoLink: e.target.value });
+ }
+
+ private repoSearchFilter(e: any) {
+ this.setState((state: Readonly, props: Readonly) => ({
+ searchValue: e.target.value,
+ }));
+ }
+
+ private triggerRepoSearch() {
+ this.setState((state: Readonly, props: Readonly) => ({
+ finalSearchValue: state.searchValue,
+ }));
+ }
+
+ // Some layout atr inspired from @Fox2Code
+ public onCreate(): JSX.Element {
+ const MListItem = (props: ListItemProps) => {
+ return (
+ <>
+ {props.part && (
+
+
+
+
+
+ {props.text}
+
+ )}
+ >
+ );
+ };
+
+ const roReposOption = (): Array => {
+ return !SharedPreferences.getBoolean("enableHideReadonlyRepositories_switch", false) ? RepoActivity.getReadOnlyRepos() : [];
+ };
+
+ const filteredRepos = roReposOption()
+ .concat(this.state.repos)
+ .filter((item) => item.name.toLowerCase().includes(this.state.finalSearchValue.toLowerCase()));
+
+ return (
+ <>
+
+
+ {filteredRepos.map((repo: RepoInterface, index: number) => (
+
+
+ {repo.name}
+ {repo.readonly ? " (Read-Only)" : ""}
+
+ {}}
+ >
+
+
+
+
+ Enabled
+
+ {
+ switch (repo.built_in_type) {
+ case "MMAR":
+ this.pref.setBoolean("repoMMARenabled", e.target.checked);
+ break;
+ case "GMR":
+ this.pref.setBoolean("repoGMRenabled", e.target.checked);
+ break;
+ default:
+ this.changeEnabledState(e.target.checked);
+ break;
+ }
+ }}
+ />
+
+
+ {
+ if (repo.website) {
+ os.open(repo.website);
+ }
+ }}
+ />
+ {
+ if (repo.support) {
+ os.open(repo.support);
+ }
+ }}
+ />
+ {
+ if (repo.donate) {
+ os.open(repo.donate);
+ }
+ }}
+ />
+ {
+ if (repo.submitModule) {
+ os.open(repo.submitModule);
+ }
+ }}
+ />
+ {
+ ons.notification
+ .confirm(
+ string.formatString(string.confirm_repo_delete, {
+ name: repo.name,
+ }) as string
+ )
+ .then((g) => {
+ if (g) {
+ this.removeRepo(repo);
+ }
+ });
+ }}
+ />
+
+ ))}
+
+ <>
+
+ {string.add_repo}
+
+
+
+ {string.cancel}
+
+
+ {string.add}
+
+
+
+ >
+ >
+ );
+ }
+}
+
+export default RepoActivity;
diff --git a/Website/src/activitys/RepoGeneratorActivity.tsx b/Website/src/activitys/RepoGeneratorActivity.tsx
index 56c03f89e..3a5d212f5 100644
--- a/Website/src/activitys/RepoGeneratorActivity.tsx
+++ b/Website/src/activitys/RepoGeneratorActivity.tsx
@@ -1,4 +1,4 @@
-import Toolbar from "@Builders/ToolbarBuilder";
+
import WebView from "@Components/WebView";
import { CSSProperties } from "react";
import AppCompatActivity from "./AppCompatActivity";
@@ -17,7 +17,7 @@ class RepoGeneratorActivity extends AppCompatActivity {
super(props);
}
- public onCreateToolbar(): Toolbar.Props {
+ public onCreateToolbar() {
return {
title: "Repo Generator",
onBackButton: this.props.popPage,
diff --git a/Website/src/activitys/SettingsActivity.tsx b/Website/src/activitys/SettingsActivity.tsx
index 689ba4db9..e6c5843c3 100644
--- a/Website/src/activitys/SettingsActivity.tsx
+++ b/Website/src/activitys/SettingsActivity.tsx
@@ -1,18 +1,16 @@
-import { List } from "react-onsenuix";
import ListViewBuilder from "@Builders/ListViewBuilder";
import pkg from "@Package";
import AppCompatActivity from "./AppCompatActivity";
import { string } from "@Strings";
-import ons from "onsenui";
import AcknowledgementsActivity from "@Activitys/AcknowledgementsActivity";
import AlertDialog from "@Builders/AlertDialog";
import SharedPreferences, { ISharedPreferences } from "@Native/SharedPreferences";
-import { link } from "googlers-tools";
import {
Brightness2Rounded,
BugReportRounded,
ExtensionRounded,
GavelRounded,
+ HideSourceRounded,
PowerInputRounded,
SourceRounded,
} from "@mui/icons-material";
@@ -20,8 +18,9 @@ import BuildConfig from "@Native/BuildConfig";
import { os } from "@Native/os";
import Icon from "@Components/Icon";
import Magisk from "@Native/Magisk";
-import Toolbar from "@Builders/ToolbarBuilder";
import RepoGeneratorActivity from "./RepoGeneratorActivity";
+import RepoActivity from "./RepoActivity";
+import { List } from "react-onsenui";
interface Props {
pushPage: any;
@@ -43,12 +42,17 @@ class SettingsActivity extends AppCompatActivity {
this.pref = new SharedPreferences();
}
+ public onBackButton(): void {
+ this.props.popPage();
+ }
+
public componentDidMount = () => {
super.componentDidMount;
+
this.setState({ libs: Object.keys(pkg.dependencies) });
};
- public onCreateToolbar(): Toolbar.Props {
+ public onCreateToolbar() {
return {
title: string.settings,
onBackButton: this.props.popPage,
@@ -67,43 +71,22 @@ class SettingsActivity extends AppCompatActivity {
content: [
{
type: "",
+ text: "Repositories",
icon: ,
- text: string.custom_repository,
- helper: {
- text: "Test",
- },
- onClick: (key) => {
- new AlertDialog.Builder()
- .setTitle(string.custom_repository)
- .setMessage("Only URLs are valid")
- .setPositiveButton("Apply", (input: string) => {
- if (input != null) {
- if (input.startsWith(">")) {
- switch (input) {
- case ">gmr":
- this.pref.setString("repo", "https://repo.dergoogler.com/modules.json");
- break;
- case ">mmar":
- this.pref.setString(
- "repo",
- "https://raw.githubusercontent.com/Magisk-Modules-Alt-Repo/json/main/modules.json"
- );
- break;
- }
- } else {
- if (link.validURL(input)) {
- this.pref.setString("repo", input);
- ons.notification.alert("Repo changed, please refresh the app");
- } else {
- ons.notification.alert("Invalid input");
- }
- }
- }
- })
- .setNegativeButtom("Cancel", () => {})
- .showPrompt();
+
+ onClick(key, pushPage) {
+ pushPage({
+ key: "repoactivity",
+ activity: RepoActivity,
+ });
},
},
+ {
+ key: "enableHideReadonlyRepositories",
+ type: "switch",
+ icon: ,
+ text: "Hide Readonly Repositories",
+ },
],
},
{
@@ -126,17 +109,17 @@ class SettingsActivity extends AppCompatActivity {
},
],
callback: (e: Event, key: string, keepDefaultFuntion: void) => {
- new AlertDialog.Builder()
- .setTitle("Sure?")
- .setMessage(
-
- Do you wanna change the language?
-
- )
- .setPositiveButton("Yes", (input: string) => {
- keepDefaultFuntion;
- })
- .showAlert();
+ const builder = AlertDialog.Builder;
+ builder.setTitle("Sure?");
+ builder.setMessage(
+
+ Do you wanna change the language?
+
+ );
+ builder.setPositiveButton("Yes", (input: string) => {
+ keepDefaultFuntion;
+ });
+ builder.show();
},
},
{
@@ -157,6 +140,9 @@ class SettingsActivity extends AppCompatActivity {
},
{
title: "Utils",
+ style: {
+ display: os.isAndroid ? "none" : "",
+ },
content: [
{
type: "",
@@ -184,7 +170,7 @@ class SettingsActivity extends AppCompatActivity {
{
type: "",
icon: ,
- text: "Acknowledgements",
+ text: string.acknowledgements,
onClick: (key, pushPage) => {
pushPage({
key: "acknowledgements",
@@ -195,7 +181,7 @@ class SettingsActivity extends AppCompatActivity {
{
type: "",
icon: ,
- text: "Issues",
+ text: string.issues,
onClick: (key, pushPage) => {
window.open("https://github.com/DerGoogler/DG-Repo/issues", "_blank");
},
diff --git a/Website/src/activitys/ViewModuleActivity.tsx b/Website/src/activitys/ViewModuleActivity.tsx
index ab59d71df..84eb25676 100644
--- a/Website/src/activitys/ViewModuleActivity.tsx
+++ b/Website/src/activitys/ViewModuleActivity.tsx
@@ -1,5 +1,4 @@
-import { Toolbar as gae, Button } from "react-onsenuix";
-import { Dialog } from "react-onsenui";
+import { Button, Dialog, ToolbarButton } from "react-onsenui";
import ons from "onsenui";
import axios from "axios";
import { DownloadRounded, InfoRounded, InstallMobileRounded, VerifiedRounded } from "@mui/icons-material";
@@ -10,26 +9,37 @@ import Alert from "@mui/material/Alert";
import AppCompatActivity from "./AppCompatActivity";
import { string } from "@Strings";
import Magisk from "@Native/Magisk";
-import Toolbar from "@Builders/ToolbarBuilder";
+import { CSSProperties } from "react";
+import { link, util } from "googlers-tools";
+import ModuleProps from "@Types/ModuleProps";
+import AlertDialog from "@Builders/AlertDialog";
interface Props {
- extra?: any;
+ extra: {
+ moduleProps: ModuleProps.PropUrl;
+ [x: string]: any;
+ };
popPage: any;
}
interface States {
notes: string;
dialogShown: boolean;
+ mProps: ModuleProps.PropUrl;
+ mFoxProps: ModuleProps.FoxProps;
}
class ViewModuleActivity extends AppCompatActivity {
public static readonly ignoreURL: bool = true;
+ public pageStyle: CSSProperties = { marginBottom: "28px" };
public constructor(props: Props | Readonly) {
super(props);
this.state = {
notes: "",
dialogShown: false,
+ mProps: this.props.extra.moduleProps,
+ mFoxProps: this.props.extra.moduleProps.foxprops,
};
}
@@ -44,27 +54,44 @@ class ViewModuleActivity extends AppCompatActivity {
.catch((error) => {
if (error.response.status === 404) {
this.setState({
- notes: `# 404: Not Found\n\n The author doesn't have created or uploaded an \`README.md\`, please try again later.\n\n\n## About Readme's\n\n- ❌ readme.md\n- ✅ README.md`,
+ notes: `# 404: Not Found\n\n The author doesn't have created or uploaded an \`README.md\`, please try again later.\n\n\n## About Readme's\n\n- readme.md\n- README.md`,
});
}
})
.then(() => {
// always executed
});
+
+ const { minMagisk, minApi, maxApi, needRamdisk, changeBoot } = this.state.mFoxProps;
+ if (minApi && minApi > 20) {
+ const builder = AlertDialog.Builder;
+ builder.setTitle("Unsupported!");
+ builder.setMessage("This module target api is higher than your device api.");
+ builder.setPositiveButton("Ok");
+ builder.setCancelable(false);
+ builder.show();
+ }
};
- public onCreateToolbar = (): Toolbar.Props => {
- const { minMagisk, minApi, maxApi, needRamdisk, changeBoot } = this.props.extra?.moduleProps;
+ public onCreateToolbar = () => {
+ // Normal props
+ const { name } = this.state.mProps;
+ // FoxProps
+ const { minMagisk, minApi, maxApi, needRamdisk, changeBoot } = this.state.mFoxProps;
return {
- title: this.props.extra.name,
+ title: this.props.extra?.name,
onBackButton: this.props.popPage,
addToolbarButton: (
<>
- {(minMagisk || minApi || maxApi || needRamdisk || changeBoot) != (null || undefined) ? (
+ {((minMagisk && minMagisk) ||
+ (minApi && minApi) ||
+ (maxApi && maxApi) ||
+ (needRamdisk && needRamdisk) ||
+ (changeBoot && changeBoot)) != (null || undefined) ? (
-
+
-
+
) : null}
>
@@ -82,7 +109,10 @@ class ViewModuleActivity extends AppCompatActivity {
};
public onCreate = () => {
- const { minMagisk, minApi, maxApi, needRamdisk, changeBoot, name, stars, alpahMMRLinstall } = this.props.extra?.moduleProps;
+ // Normal props
+ const { name } = this.state.mProps;
+ // FoxProps
+ const { minMagisk, minApi, maxApi, needRamdisk, changeBoot } = this.state.mFoxProps;
const { download, id } = this.props.extra;
const { verified, low } = this.props.extra?.moduleOptions;
return (
@@ -91,26 +121,19 @@ class ViewModuleActivity extends AppCompatActivity {
style={{ padding: "8px", height: "100%" }}
className={new SharedPreferences().getBoolean("enableDarkmode_switch", false) ? "markdown-body-dark" : "markdown-body-light"}
>
- {
- /*
- // @ts-ignore */
- (() => {
- if (verified) {
- return (
- } severity="success">
- {string.module_verified}
-
- );
- }
- })()
- }
-
+ {verified && (
+ } severity="success">
+ {string.module_verified}
+
+ )}
+
-
+
{
Informations
- {(() => {
- if (minMagisk != (null || undefined)) {
- return (
-
-
- Min. Magisk
-
- Magisk.VERSION_CODE ? "red" : "") : "",
- }}
- >
- {minMagisk}
-
-
- );
- } else {
- return null;
- }
- })()}
- {(() => {
- if (minApi != (null || undefined)) {
- return (
-
- Min. Android
- {minApi}
-
- );
- } else {
- return null;
- }
- })()}
- {(() => {
- if (maxApi != (null || undefined)) {
- return (
-
- Max. Android
- {maxApi}
-
- );
- } else {
- return null;
- }
- })()}
- {(() => {
- if (needRamdisk != (null || undefined)) {
- return (
-
- needsRamdisk
- {needRamdisk}
-
- );
- } else {
- return null;
- }
- })()}
- {(() => {
- if (changeBoot != (null || undefined)) {
- return (
-
- changeBoot
- {changeBoot}
-
- );
- } else {
- return null;
- }
- })()}
+ {minMagisk != (null || undefined) && (
+
+
+ Min. Magisk
+
+ Magisk.VERSION_CODE ? "red" : "") : "",
+ }}
+ >
+ {minMagisk}
+
+
+ )}
+ {minApi != (null || undefined) && (
+
+ Min. Android
+ {minApi}
+
+ )}
+ {maxApi != (null || undefined) && (
+
+ Max. Android
+ {maxApi}
+
+ )}
+ {needRamdisk != (null || undefined) && (
+
+ needsRamdisk
+ {needRamdisk}
+
+ )}
+ {changeBoot != (null || undefined) && (
+
+ changeBoot
+ {changeBoot}
+
+ )}
diff --git a/Website/src/activitys/fragments/DeviceModuleFragment.tsx b/Website/src/activitys/fragments/DeviceModuleFragment.tsx
index 6779bd35b..b9d190e0b 100644
--- a/Website/src/activitys/fragments/DeviceModuleFragment.tsx
+++ b/Website/src/activitys/fragments/DeviceModuleFragment.tsx
@@ -1,7 +1,6 @@
import { Component } from "react";
import DeviceModule from "@Components/DeviceModule";
import { PushProps } from "@Activitys/MainActivity";
-import { Page } from "react-onsenuix";
import File from "@Native/File";
interface Props {
@@ -29,7 +28,7 @@ class DeviceModuleFragment extends Component
{
return ;
});
return (
-
+ <>
{
>
{moduels}
-
+ >
);
};
}
diff --git a/Website/src/activitys/fragments/ExploreModuleFragment.tsx b/Website/src/activitys/fragments/ExploreModuleFragment.tsx
index 1ecd13177..99f18675e 100644
--- a/Website/src/activitys/fragments/ExploreModuleFragment.tsx
+++ b/Website/src/activitys/fragments/ExploreModuleFragment.tsx
@@ -1,42 +1,53 @@
-import { Component, LegacyRef } from "react";
-import { SearchInput, ProgressCircular, Row } from "react-onsenui";
-import { Button, Page } from "react-onsenuix";
+import { Component } from "react";
+import { ProgressCircular, Row } from "react-onsenui";
import axios from "axios";
import ExploreModule from "@Components/ExploreModule";
import SharedPreferences from "@Native/SharedPreferences";
import { PushProps } from "@Activitys/MainActivity";
-import { SearchRounded } from "@mui/icons-material";
import { os } from "@Native/os";
import ons from "onsenui";
import { string } from "@Strings";
-import { isTablet } from "react-device-detect";
+import { isDesktop, isTablet } from "react-device-detect";
+import RepoActivity, { RepoInterface } from "@Activitys/RepoActivity";
+import Toast from "@Native/Toast";
+import { Searchbar } from "@Components/Searchbar";
+import ModuleProps from "@Types/ModuleProps";
interface Props {
pushPage(...arg: any): PushProps;
}
interface States {
- modulesIndex: any[any];
- currentSerachText: string;
- search: string;
+ modulesIndex: Array;
moduleOptions: any[any];
loading: boolean;
+ searchValue: string;
+ finalSearchValue: string;
+}
+
+interface ModuleObject {
+ id: string;
+ last_update: number;
+ notes_url: string;
+ prop_url: string;
+ props: ModuleProps.PropUrl;
+ stars: number;
+ zip_url: string;
}
class ExploreModuleFragment extends Component {
- private searchBar: LegacyRef | undefined;
- private prefManager: SharedPreferences;
+ private pref: SharedPreferences;
public constructor(props: Props | Readonly) {
super(props);
this.state = {
modulesIndex: [],
- currentSerachText: "",
- search: "",
moduleOptions: {},
loading: true,
+ searchValue: "",
+ finalSearchValue: "",
};
- this.prefManager = new SharedPreferences();
+ this.pref = new SharedPreferences();
}
public componentDidMount = () => {
@@ -49,24 +60,31 @@ class ExploreModuleFragment extends Component {
this.setState({ loading: false });
}, 2000);
- axios
- .get(this.prefManager.getString("repo", "https://raw.githubusercontent.com/Magisk-Modules-Alt-Repo/json/main/modules.json"))
- .then((response) => {
- const modules = response.data.modules;
- this.setState({
- modulesIndex: modules,
- });
- })
- .catch((error) => {
- this.setState({
- modulesIndex: [],
- });
- })
- .then(() => {
- // always executed
+ RepoActivity.getReadOnlyRepos()
+ .concat(this.pref.getJSON>("repos", []))
+ .map((repo: RepoInterface) => {
+ if (repo.isOn) {
+ axios
+ .get(repo.modules)
+ .then((response) => {
+ const modules = response.data.modules;
+ this.setState((state, props) => ({
+ modulesIndex: state.modulesIndex.concat(modules /*.map((item: any) => ({ ...item }))*/),
+ }));
+ })
+ .catch((error) => {
+ this.setState({
+ modulesIndex: [],
+ });
+ Toast.makeText(error, Toast.LENGTH_SHORT).show();
+ })
+ .then(() => {
+ // always executed
+ });
+ } // If the repo is disabled, do nothing.
});
- axios.get("https://dergoogler.com/repo/moduleOptions.json").then((response) => {
+ axios.get("https://repo.dergoogler.com/moduleOptions.json").then((response) => {
this.setState({
moduleOptions: response.data,
});
@@ -76,26 +94,28 @@ class ExploreModuleFragment extends Component {
public componentDidCatch = () => {};
private filter = (e: any) => {
- this.setState({ currentSerachText: e.target.value.toLowerCase() });
+ this.setState((state: Readonly, props: Readonly) => ({
+ searchValue: e.target.value,
+ }));
};
private triggerSearch = () => {
this.setState((state: Readonly, props: Readonly) => ({
- search: state.currentSerachText,
+ finalSearchValue: state.searchValue,
}));
};
public render = () => {
- const { search, loading, modulesIndex } = this.state;
+ const { loading, modulesIndex, searchValue, finalSearchValue } = this.state;
- const resultsRender = [];
+ const resultsRender: Array = [];
for (var i = 0; i < modulesIndex.length; i += 2) {
resultsRender.push({this.cardRender(modulesIndex.slice(i, i + 2))}
);
}
return (
-
+ <>
{
flexDirection: "column",
}}
>
-
+
{
)}
-
+ >
);
};
- private cardRender(map: Array) {
- return map.map((item: any) => {
- return (
-
- );
- });
+ private cardRender(map: Array) {
+ const filteredModules = map.filter((item) => item.id.toLowerCase().includes(this.state.finalSearchValue.toLowerCase()));
+
+ return filteredModules
+ .sort((a, b) => (a.id > b.id ? 1 : -1))
+ .map((item) => {
+ return (
+
+ );
+ });
}
}
diff --git a/Website/src/builders/AlertDialog.tsx b/Website/src/builders/AlertDialog.tsx
index 12b8bd014..f9f9184f1 100644
--- a/Website/src/builders/AlertDialog.tsx
+++ b/Website/src/builders/AlertDialog.tsx
@@ -2,171 +2,140 @@ import ons from "onsenui";
import { isValidElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
-namespace AlertDialog {
- interface Alert {
- title: string;
- messageHTML: string | JSX.Element;
- cancelable: boolean;
- callback: Function;
- buttons: AlertButtons;
- }
+interface Alert {
+ title: string;
+ messageHTML: string | JSX.Element;
+ cancelable: boolean;
+ callback: Function;
+ buttons: AlertButtons;
+}
- interface AlertButtons {
- positive: AlertButton;
- negative: AlertButton;
- }
+interface AlertButtons {
+ positive: AlertButton;
+ negative: AlertButton;
+}
- interface AlertButton {
- title: string;
- callback: Function | undefined;
- }
+interface AlertButton {
+ title: string;
+ callback: Function | undefined;
+}
- interface AlertOptions {
- message?: string;
- messageHTML?: string | JSX.Element;
- buttonLabel?: string;
- buttonLabels?: string[];
- primaryButtonIndex?: number;
- cancelable?: boolean;
- animation?: string;
- title?: string;
- modifier?: string;
- callback?: any;
- id?: string;
- }
+type BuilderConstructorOmit = Omit;
- /**
- * Building dialogs
- */
- export class Builder {
- private dialog: Alert;
-
- public constructor() {
- this.dialog = {
- title: "",
- messageHTML: "",
- cancelable: true,
- callback: () => {},
- buttons: {
- positive: {
- title: "",
- callback: () => {},
- },
- negative: {
- title: "",
- callback: () => {},
- },
- },
- };
- }
+interface Builder {
+ setTitle(value: string): BuilderConstructorOmit<"setTitle">;
+ setMessage(value: string | JSX.Element): BuilderConstructorOmit<"setMessage">;
+ setPositiveButton(title: string, callback?: Function): BuilderConstructorOmit<"setPositiveButton">;
+ setNegativeButtom(title: string, callback?: Function): BuilderConstructorOmit<"setNegativeButtom">;
+ setCancelable(cancel: boolean): BuilderConstructorOmit<"setCancelable">;
+ show(): void;
+}
- /**
- * @prompt Not supported
- */
- public setTitle(value: string): Builder {
- this.dialog.title = value;
- return this;
- }
+interface AlertOptions {
+ message?: string;
+ messageHTML?: string | JSX.Element;
+ buttonLabel?: string;
+ buttonLabels?: string[];
+ primaryButtonIndex?: number;
+ cancelable?: boolean;
+ animation?: string;
+ title?: string;
+ modifier?: string;
+ callback?: any;
+ id?: string;
+}
- public setMessage(value: string | JSX.Element): Builder {
- if (isValidElement(value)) {
- this.dialog.messageHTML = renderToStaticMarkup(value);
- } else {
- this.dialog.messageHTML = value;
- }
- return this;
- }
+class AlertDialogClass implements Builder {
+ private dialog: Alert;
- /**
- * @prompt Not supported
- */
- public setPositiveButton(title: string, callback?: Function): Builder {
- this.dialog.buttons.positive.title = title;
- this.dialog.buttons.positive.callback = callback;
- return this;
- }
+ public constructor() {
+ this.dialog = {
+ title: "",
+ messageHTML: "",
+ cancelable: true,
+ callback: () => {},
+ buttons: {
+ positive: {
+ title: "",
+ callback: () => {},
+ },
+ negative: {
+ title: "",
+ callback: () => {},
+ },
+ },
+ };
+ }
- /**
- * @prompt Not supported
- */
- public setNegativeButtom(title: string, callback?: Function): Builder {
- this.dialog.buttons.negative.title = title;
- this.dialog.buttons.negative.callback = callback;
- return this;
- }
+ public setTitle(value: string): BuilderConstructorOmit<"setTitle"> {
+ this.dialog.title = value;
+ return this;
+ }
- /**
- * Creates an custom callback for an prompt dialog
- * @alert Not supported
- * @deprecated
- */
- public setPromptCallback(callback: Function): Builder {
- this.dialog.callback = callback;
- return this;
+ public setMessage(value: string | JSX.Element): BuilderConstructorOmit<"setMessage"> {
+ if (isValidElement(value)) {
+ this.dialog.messageHTML = renderToStaticMarkup(value);
+ } else {
+ this.dialog.messageHTML = value;
}
+ return this;
+ }
- public setCancelable(cancel: boolean): Builder {
- this.dialog.cancelable = cancel;
- return this;
- }
+ public setPositiveButton(title: string, callback?: Function): BuilderConstructorOmit<"setPositiveButton"> {
+ this.dialog.buttons.positive.title = title;
+ this.dialog.buttons.positive.callback = callback;
+ return this;
+ }
- public showAlert(): Alert & Void {
- const { positive, negative } = this.dialog.buttons;
- const { title, messageHTML } = this.dialog;
- const pla: AlertOptions = {
- buttonLabels: [],
- animation: "default",
- primaryButtonIndex: 0,
- cancelable: true,
- callback: (index: number) => {
- switch (index) {
- case 0:
- if (typeof positive.callback == "function") positive.callback();
- break;
- case 1:
- if (typeof negative.callback == "function") negative.callback();
- break;
- default:
- // Nothing
- break;
- }
- },
- };
- pla.messageHTML = messageHTML;
- pla.title = title;
- if (positive.title) {
- pla.buttonLabels?.push(positive.title);
- }
- if (negative.title) {
- pla.buttonLabels?.push(negative.title);
- }
- // @ts-ignore
- ons.notification.confirm(pla);
- }
+ public setNegativeButtom(title: string, callback?: Function): BuilderConstructorOmit<"setNegativeButtom"> {
+ this.dialog.buttons.negative.title = title;
+ this.dialog.buttons.negative.callback = callback;
+ return this;
+ }
- public showPrompt(): Alert & Void {
- const { positive, negative } = this.dialog.buttons;
- const { title, callback, messageHTML, cancelable } = this.dialog;
- ons.notification
- .prompt({
- // @ts-ignore
- messageHTML: messageHTML,
- buttonLabels: [negative.title, positive.title],
- title: title,
- // @ts-ignore
- isPrompt: true,
- // @ts-ignore
- autofocus: true,
- // @ts-ignore
- submitOnEnter: true,
- })
- .then((input) => {
- if (typeof positive.callback == "function") {
- positive.callback(input);
- }
- });
+ public setCancelable(cancel: boolean): BuilderConstructorOmit<"setCancelable"> {
+ this.dialog.cancelable = cancel;
+ return this;
+ }
+
+ public show(): void {
+ const { positive, negative } = this.dialog.buttons;
+ const { title, messageHTML } = this.dialog;
+ const pla: AlertOptions = {
+ buttonLabels: [],
+ animation: "default",
+ primaryButtonIndex: 0,
+ cancelable: true,
+ callback: (index: number) => {
+ switch (index) {
+ case 0:
+ if (typeof positive.callback == "function") positive.callback();
+ break;
+ case 1:
+ if (typeof negative.callback == "function") negative.callback();
+ break;
+ default:
+ // Nothing
+ break;
+ }
+ },
+ };
+ pla.messageHTML = messageHTML;
+ pla.title = title;
+ if (positive.title) {
+ pla.buttonLabels?.push(positive.title);
+ }
+ if (negative.title) {
+ pla.buttonLabels?.push(negative.title);
}
+ // @ts-ignore
+ ons.notification.confirm(pla);
}
}
+type AlertDialog = typeof AlertDialog[keyof typeof AlertDialog];
+const AlertDialog: { readonly Builder: Builder } = {
+ Builder: new AlertDialogClass(),
+} as const;
+
export default AlertDialog;
diff --git a/Website/src/builders/ListViewBuilder.tsx b/Website/src/builders/ListViewBuilder.tsx
index f15abded6..f9c266264 100644
--- a/Website/src/builders/ListViewBuilder.tsx
+++ b/Website/src/builders/ListViewBuilder.tsx
@@ -1,6 +1,5 @@
import { Component, isValidElement } from "react";
import { ListItem, ListTitle, Select, Switch } from "react-onsenui";
-import { List } from "react-onsenuix";
import ons from "onsenui";
import Gesture from "@Components/Gesture";
import SharedPreferences, { ISharedPreferences } from "@Native/SharedPreferences";
@@ -95,10 +94,10 @@ class ListViewBuilder extends Component {
return data.map((header: IListInterface) => (
<>
-
+
>
))}
diff --git a/Website/src/builders/ToolbarBuilder.tsx b/Website/src/builders/ToolbarBuilder.tsx
index e6e0757c9..092a29b3c 100644
--- a/Website/src/builders/ToolbarBuilder.tsx
+++ b/Website/src/builders/ToolbarBuilder.tsx
@@ -1,39 +1,38 @@
import { Component } from "react";
-import { BackButton, Toolbar as Cockbar } from "react-onsenuix";
+import { BackButton, Toolbar } from "react-onsenui";
-namespace Toolbar {
- export interface Props {
- /**
- * It's used to display a title on the toolbar
- */
- title: string;
- /**
- * Due not use it with `addToolbarButton="left"`!
- *
- * Remove the `onBackButton` attr or put `false` inside!
- */
- onBackButton?: boolean;
- addToolbarButton?: React.ReactNode;
- addToolbarButtonPosition?: "left" | "right";
- }
+interface Props {
+ /**
+ * It's used to display a title on the toolbar
+ */
+ title: string;
+ /**
+ * Due not use it with `addToolbarButton="left"`!
+ *
+ * Remove the `onBackButton` attr or put `false` inside!
+ */
+ onBackButton?: boolean;
+ addToolbarButton?: React.ReactNode;
+ addToolbarButtonPosition?: "left" | "right";
+ modifier?: string;
+}
- export class Builder extends Component {
- public render() {
- const { title, onBackButton, addToolbarButton, addToolbarButtonPosition } = this.props;
- return (
-
-
- {/**
+export class ToolbarBuilder extends Component
{
+ public render() {
+ const { title, onBackButton, addToolbarButton, addToolbarButtonPosition, modifier } = this.props;
+ return (
+
+
+ {/**
// @ts-ignore */}
- {onBackButton ? : null}
- {addToolbarButtonPosition === "left" ? addToolbarButton : null}
-
- {title}
- {addToolbarButtonPosition === "right" ? addToolbarButton : null}
-
- );
- }
+ {onBackButton ? : null}
+ {addToolbarButtonPosition === "left" ? addToolbarButton : null}
+
+ {title}
+ {addToolbarButtonPosition === "right" ? addToolbarButton : null}
+
+ );
}
}
-export default Toolbar;
+export default ToolbarBuilder;
diff --git a/Website/src/components/ContentBody.tsx b/Website/src/components/ContentBody.tsx
index 5edb43b44..449b5c1ae 100644
--- a/Website/src/components/ContentBody.tsx
+++ b/Website/src/components/ContentBody.tsx
@@ -2,7 +2,7 @@ import { os } from "@Native/os";
import SharedPreferences from "@Native/SharedPreferences";
import { CSSProperties } from "react";
import { isMobile } from "react-device-detect";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import ViewX from "./ViewX";
/**
* ContentBody is an optional component, to make the view better on desktop
@@ -28,19 +28,19 @@ class ContentBody extends ViewX {
}
}
- public createView(data: ViewXRenderData<{}, {}, HTMLElement>): JSX.Element {
+ public createView(): JSX.Element {
return (
- {data.p.children}
+ {this.props.children}
);
}
diff --git a/Website/src/components/DeviceModule.tsx b/Website/src/components/DeviceModule.tsx
index c528d6421..3ee572dee 100644
--- a/Website/src/components/DeviceModule.tsx
+++ b/Website/src/components/DeviceModule.tsx
@@ -5,7 +5,7 @@ import Log from "@Native/Log";
import { DeleteRounded, RefreshRounded } from "@mui/icons-material";
import SharedPreferences from "@Native/SharedPreferences";
import { string } from "@Strings";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import ViewX from "./ViewX";
interface Props {
module: string;
@@ -66,25 +66,21 @@ class DeviceModule extends ViewX {
}
};
- public createView(data: ViewXRenderData): JSX.Element {
- const module = data.p.module;
- const { id, name, version, versionCode, author, description } = data.s.props;
- const { isEnabled, isSwitchDisabled } = data.s;
+ public createView(): JSX.Element {
+ const module = this.props.module;
+ const { id, name, version, versionCode, author, description } = this.state.props;
+ const { isEnabled, isSwitchDisabled } = this.state;
return (
<>
-
+
{name}
{
diff --git a/Website/src/components/ErrorBoundary.tsx b/Website/src/components/ErrorBoundary.tsx
index 0e2e5f698..c2aeff7e1 100644
--- a/Website/src/components/ErrorBoundary.tsx
+++ b/Website/src/components/ErrorBoundary.tsx
@@ -1,6 +1,7 @@
import Log from "@Native/Log";
import { ErrorInfo, ReactNode } from "react";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import { Page, Toolbar } from "react-onsenui";
+import ViewX from "./ViewX";
interface Props {
children: ReactNode;
@@ -10,7 +11,7 @@ interface Props {
interface States {
hasError: boolean;
error: Error | string | null;
- errorInfo: ErrorInfo | string | null;
+ errorInfo: ErrorInfo | null;
}
class ErrorBoundary extends ViewX {
@@ -47,24 +48,22 @@ class ErrorBoundary extends ViewX {
);
}
- public createView(data: ViewXRenderData): JSX.Element {
- if (data.s.hasError) {
+ public createView(): JSX.Element {
+ const { hasError, errorInfo } = this.state;
+ if (hasError) {
return (
-
-
Something went wrong.
-
- {data.s.hasError && data.s.hasError.toString()}
-
-
- {
- // @ts-ignore
- data.s.errorInfo?.componentStack
- }
-
-
+ (
+
+ Something went wrong
+
+ )}
+ >
+ {errorInfo?.componentStack}
+
);
}
- return data.p.children as any;
+ return this.props.children as any;
}
}
diff --git a/Website/src/components/ExploreModule.tsx b/Website/src/components/ExploreModule.tsx
index e4e099bfe..308f7bef2 100644
--- a/Website/src/components/ExploreModule.tsx
+++ b/Website/src/components/ExploreModule.tsx
@@ -6,9 +6,11 @@ import ViewModuleActivity from "@Activitys/ViewModuleActivity";
import Log from "@Native/Log";
import { VerifiedRounded } from "@mui/icons-material";
import { os } from "@Native/os";
-import { isTablet } from "react-device-detect";
-import { dom, link } from "googlers-tools";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import { isDesktop, isTablet } from "react-device-detect";
+import { link } from "googlers-tools";
+import ViewX from "./ViewX";
+import { string } from "@Strings";
+import ModuleProps from "@Types/ModuleProps";
interface Props {
notesUrl?: string;
@@ -17,9 +19,10 @@ interface Props {
moduleOptions: ModuleOptions[];
stars?: int;
last_update?: any;
+ fullItem: any;
getId: any;
- searchState?: string;
propsUrl: string;
+ props: ModuleProps.PropUrl;
}
interface ModuleOptions {
@@ -29,22 +32,7 @@ interface ModuleOptions {
}
interface States {
- props: {
- id?: string;
- name?: string;
- version?: string;
- versionCode?: int;
- author?: string;
- description?: string;
- minApi?: int;
- maxApi?: int;
- minMagisk?: int;
- needRamdisk?: boolean;
- support?: string;
- donate?: string;
- config?: string;
- changeBoot?: boolean;
- };
+ props: Partial;
}
class ExploreModule extends ViewX {
@@ -63,37 +51,29 @@ class ExploreModule extends ViewX {
}
public componentDidMount = () => {
- const { propsUrl } = this.props;
- const { props } = this.state;
- axios.get(propsUrl).then((response) => {
- this.setState({
- props: Properties.parseToProperties(response.data),
+ const { propsUrl, props } = this.props;
+ if (typeof props == "object") {
+ this.setState({ props: props });
+ } else {
+ axios.get(propsUrl as string).then((response) => {
+ let tmp = Properties.parseToProperties(response.data);
+ tmp.foxprops = {
+ minApi: null as any,
+ maxApi: null as any,
+ minMagisk: null as any,
+ needRamdisk: null as any,
+ support: null as any,
+ donate: null as any,
+ config: null as any,
+ changeBoot: null as any,
+ };
+ this.setState({
+ props: tmp,
+ });
});
- });
+ }
};
- public componentDidUpdate() {
- const { searchState } = this.props;
- dom.findBy(this.cardName, (ref) => {
- if (searchState != "") {
- const search = ref.textContent || ref.innerText;
- if (search.toLowerCase().indexOf(searchState) > -1) {
- dom.findBy(this.searchedCard, (ref: HTMLElement) => {
- ref.style.display = "";
- });
- } else {
- dom.findBy(this.searchedCard, (ref: HTMLElement) => {
- ref.style.display = "none";
- });
- }
- } else {
- dom.findBy(this.searchedCard, (ref: HTMLElement) => {
- ref.style.display = "";
- });
- }
- });
- }
-
private formatDate(date: Date) {
var hours = date.getHours();
var minutes = date.getMinutes();
@@ -130,96 +110,92 @@ class ExploreModule extends ViewX {
}
}
- public createView(data: ViewXRenderData): JSX.Element {
- const { notesUrl, downloadUrl, pushPage, moduleOptions, stars, last_update, getId } = data.p;
- const { props } = data.s;
+ public createView(): JSX.Element {
+ const { notesUrl, downloadUrl, pushPage, moduleOptions, stars, last_update, getId, fullItem } = this.props;
+ const { props } = this.state;
const isVerified = moduleOptions[getId]?.verified;
const _display = moduleOptions[getId]?.display;
return this.checkDeviceSize(
- <>
- {
- // Make an fake path. Note: The page should not refreshed!
- link.setURL((set, currentPath) => {
- set(`view_${props.id}`, `view_${props.id}`, `${currentPath}/?module=${props.id}`);
- });
+
{
+ // Make an fake path. Note: The page should not refreshed!
+ link.setURL((set, currentPath) => {
+ set(`view_${props.id}`, `view_${props.id}`, `${currentPath}/?module=${props.id}`);
+ });
- pushPage({
- key: `view_${props.id}`,
- activity: ViewModuleActivity,
- extra: {
- name: props.name,
- download: downloadUrl,
- id: getId,
- author: props.author,
- notes: notesUrl,
- stars: stars,
- moduleOptions: {
- verified: isVerified,
- },
- moduleProps: {
- minMagisk: props.minMagisk,
- minApi: props.minApi,
- maxApi: props.maxApi,
- needRamdisk: props?.needRamdisk,
- changeBoot: props.changeBoot,
- },
+ pushPage({
+ key: `view_${props.id}`,
+ activity: ViewModuleActivity,
+ extra: {
+ name: props.name,
+ download: downloadUrl,
+ id: getId,
+ author: props.author,
+ notes: notesUrl,
+ stars: stars,
+ moduleOptions: {
+ verified: isVerified,
},
- });
- }}
- >
- {/*
+ moduleProps: props,
+ },
+ });
+ }}
+ >
+ {/*
// @ts-ignore */}
-
-
-
-
-
- {props.name}
+
+
+
+
+
+ {props.name}
- {(() => {
- if (isVerified) {
- return (
- <>
- {" "}
-
- >
- );
- } else {
- return null;
- }
- })()}
-
-
-
-
-
- {props.version} ({props.versionCode}) / {props.author}
-
- {props.description}
- Last update: {this.formatDate(new Date(last_update))}
-
-
-
-
- >
+ {(() => {
+ if (isVerified) {
+ return (
+ <>
+ {" "}
+
+ >
+ );
+ } else {
+ return null;
+ }
+ })()}
+
+
+
+
+
+ {props.version} ({props.versionCode}) / {props.author}
+
+ {props.description}
+
+ {string.formatString(string.last_updated, {
+ date: this.formatDate(new Date(last_update)),
+ })}
+
+
+
+
+
);
}
}
diff --git a/Website/src/components/Gesture.tsx b/Website/src/components/Gesture.tsx
index a0ab8ff36..e8d19b024 100644
--- a/Website/src/components/Gesture.tsx
+++ b/Website/src/components/Gesture.tsx
@@ -1,6 +1,6 @@
import { createRef, RefObject, ReactNode } from "react";
import { dom } from "googlers-tools";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import ViewX from "./ViewX";
interface Props {
event:
@@ -42,8 +42,8 @@ class Gesture extends ViewX {
});
}
- public createView(data: ViewXRenderData): JSX.Element {
- return {data.p.children}
;
+ public createView(): JSX.Element {
+ return {this.props.children}
;
}
}
diff --git a/Website/src/components/HighlightMarkdown.tsx b/Website/src/components/HighlightMarkdown.tsx
index ac77e649d..b54e16211 100644
--- a/Website/src/components/HighlightMarkdown.tsx
+++ b/Website/src/components/HighlightMarkdown.tsx
@@ -1,48 +1,66 @@
-import Markdown from "marked-react";
-import { LightAsync as SyntaxHighlighter } from "react-syntax-highlighter";
-import { github } from "react-syntax-highlighter/dist/cjs/styles/hljs";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import Markdown from "markdown-to-jsx";
+import { createRef, RefObject } from "react";
+import ViewX from "./ViewX";
+import Anchor from "./dapi/Anchor";
+import Video from "./dapi/Video";
+import DiscordWidget from "./dapi/DiscordWidget";
+import Checkmark from "./icons/Checkmark";
+import Dangermark from "./icons/Dangermark";
+import Warnmark from "./icons/Warnmark";
+import hljs from "highlight.js";
+import { dom } from "googlers-tools";
interface IProps {
children: string;
}
class HighlightedMarkdown extends ViewX {
+ private ref: RefObject;
public constructor(props: any) {
super(props);
- }
-
- public componentDidMount() {}
- public createView(data: ViewXRenderData): JSX.Element {
- const renderer = {
- code(snippet: any, lang: any) {
- return ;
- },
- };
+ this.ref = createRef();
+ }
- return ;
+ public componentDidMount() {
+ dom.findBy(this.ref, (ref: HTMLDivElement) => {
+ ref.querySelectorAll("pre code").forEach((block: any) => {
+ hljs.highlightBlock(block);
+ });
+ });
}
- private codeblock({
- code,
- lang,
- className,
- children,
- ...props
- }: {
- code: any;
- lang: any;
- className: string | undefined;
- children: React.ReactNode & React.ReactNode[];
- }) {
- const match = /language-(\w+)/.exec(className || "");
- return !lang && match ? (
-
- ) : (
-
- {children}
-
+ public createView(): JSX.Element {
+ return (
+
+
+
);
}
}
diff --git a/Website/src/components/Icon.tsx b/Website/src/components/Icon.tsx
index a595a0d49..f7bb8ad89 100644
--- a/Website/src/components/Icon.tsx
+++ b/Website/src/components/Icon.tsx
@@ -1,7 +1,7 @@
import { OverridableComponent } from "@mui/material/OverridableComponent";
import { SvgIconProps, SvgIconTypeMap } from "@mui/material/SvgIcon";
import SharedPreferences, { ISharedPreferences } from "@Native/SharedPreferences";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import ViewX from "./ViewX";
interface IProps extends SvgIconProps {
icon: OverridableComponent;
@@ -22,13 +22,19 @@ class Icon extends ViewX {
super(props);
this.pref = new SharedPreferences();
this.isDarkmode = this.pref.getBoolean("enableDarkmode_switch", false);
+
+ this.createView = this.createView.bind(this);
}
- public createView(data: ViewXRenderData): JSX.Element {
+ public createView(): JSX.Element {
+ const { keepLight, ...rest } = this.props;
return (
);
}
diff --git a/Website/src/components/Searchbar.tsx b/Website/src/components/Searchbar.tsx
new file mode 100644
index 000000000..d9d27a012
--- /dev/null
+++ b/Website/src/components/Searchbar.tsx
@@ -0,0 +1,68 @@
+import { SearchRounded } from "@mui/icons-material";
+import { Button, SearchInput } from "react-onsenui";
+import ViewX from "./ViewX";
+
+interface SearchbarProps {
+ placeholder: string;
+ onInputChange: (e: Event) => void;
+ onButtonClick: () => void;
+}
+
+class Searchbar extends ViewX {
+ public constructor(props: SearchbarProps | Readonly) {
+ super(props);
+ this.createView = this.createView.bind(this);
+ }
+
+ public createView(): JSX.Element {
+ const { placeholder, onInputChange, onButtonClick } = this.props;
+
+ return (
+
+ );
+ }
+}
+
+export { Searchbar };
diff --git a/Website/src/components/TabWrapper.tsx b/Website/src/components/TabWrapper.tsx
new file mode 100644
index 000000000..a4e16183f
--- /dev/null
+++ b/Website/src/components/TabWrapper.tsx
@@ -0,0 +1,25 @@
+import { Page } from "react-onsenui";
+import ViewX from "./ViewX";
+
+interface Props {
+ element: React.ElementType;
+ props: any;
+}
+
+class TabWrapper extends ViewX {
+ public constructor(props: Props | Readonly) {
+ super(props);
+ }
+
+ public createView(): JSX.Element {
+ const Element = this.props.element;
+ const props = this.props.props;
+ return (
+
+
+
+ );
+ }
+}
+
+export { TabWrapper };
diff --git a/Website/src/components/ViewX.tsx b/Website/src/components/ViewX.tsx
new file mode 100644
index 000000000..5b6b88146
--- /dev/null
+++ b/Website/src/components/ViewX.tsx
@@ -0,0 +1,27 @@
+import React from "react";
+
+type ViewXTypeProps = React.HTMLAttributes & P;
+
+abstract class ViewX extends React.Component, S, SS> {
+ public constructor(props: ViewXTypeProps | Readonly>) {
+ super(props);
+
+ this.createView = this.createView.bind(this);
+ }
+
+ /**
+ * Normal method to render
+ */
+ public createView(): JSX.Element {
+ return <>>;
+ }
+
+ /**
+ * @deprecated
+ */
+ public render(): React.ReactNode {
+ return ;
+ }
+}
+
+export default ViewX;
diff --git a/Website/src/components/WebView.tsx b/Website/src/components/WebView.tsx
index d4663e71d..fcd2ae433 100644
--- a/Website/src/components/WebView.tsx
+++ b/Website/src/components/WebView.tsx
@@ -1,5 +1,5 @@
import objectAssign from "object-assign";
-import { ViewX, ViewXRenderData } from "react-onsenuix";
+import ViewX from "./ViewX";
interface Props {
url: string;
@@ -57,7 +57,7 @@ class WebView extends ViewX {
super(props);
}
- public createView(data: ViewXRenderData): JSX.Element {
+ public createView(): JSX.Element {
const {
url,
allowFullScreen,
diff --git a/Website/src/components/dapi/Anchor.tsx b/Website/src/components/dapi/Anchor.tsx
new file mode 100644
index 000000000..8a494c7fe
--- /dev/null
+++ b/Website/src/components/dapi/Anchor.tsx
@@ -0,0 +1,43 @@
+import SharedPreferences from "@Native/SharedPreferences";
+import { os } from "@Native/os";
+import { util } from "googlers-tools";
+import ViewX from "@Components/ViewX";
+
+interface AnchorProps {
+ download?: any;
+ href: string;
+ hrefLang?: string | undefined;
+ media?: string | undefined;
+ ping?: string | undefined;
+ rel?: string | undefined;
+ target?: string | undefined;
+ type?: string | undefined;
+ children: React.ReactNode | undefined;
+}
+
+class Anchor extends ViewX {
+ public createView(): JSX.Element {
+ const { download, href, hrefLang, media, ping, rel, target, type, children } = this.props;
+ return (
+ <>
+ {
+ os.open(href);
+ }}
+ style={{ cursor: "pointer", color: SharedPreferences.getBoolean("enableDarkmode_switch", false) ? "#bb86fc" : "#4a148c" }}
+ >
+ {children}
+
+ >
+ );
+ }
+}
+
+export default Anchor;
diff --git a/Website/src/components/dapi/DiscordWidget.tsx b/Website/src/components/dapi/DiscordWidget.tsx
new file mode 100644
index 000000000..6dde86ab6
--- /dev/null
+++ b/Website/src/components/dapi/DiscordWidget.tsx
@@ -0,0 +1,37 @@
+import ViewX from "@Components/ViewX";
+import { util } from "googlers-tools";
+
+type Theme = "light" | "dark";
+
+interface DiscordWidgetProps {
+ token?: string | number | undefined;
+ width?: string | number | undefined;
+ height?: string | number | undefined;
+ theme?: Theme | undefined;
+}
+
+class DiscordWidget extends ViewX {
+ public createView(): JSX.Element {
+ const { token, width, height, theme } = this.props;
+ return (
+ <>
+
+ >
+ );
+ }
+}
+
+export default DiscordWidget;
diff --git a/Website/src/components/dapi/Video.tsx b/Website/src/components/dapi/Video.tsx
new file mode 100644
index 000000000..2e7ec56dc
--- /dev/null
+++ b/Website/src/components/dapi/Video.tsx
@@ -0,0 +1,61 @@
+import ViewX from "@Components/ViewX";
+import { util } from "googlers-tools";
+import { CSSProperties } from "react";
+import { isDesktop } from "react-device-detect";
+
+declare type Type = `video/${string}`;
+
+interface VideoProps {
+ src: string;
+ type: Type;
+ controls?: boolean;
+ poster?: string;
+ noSupportText?: string;
+ style?: CSSProperties | string | undefined;
+}
+
+interface State {}
+
+type E = HTMLVideoElement | HTMLIFrameElement;
+
+class Video extends ViewX {
+ public createView(): JSX.Element {
+ const { src, type, controls, noSupportText, style, poster } = this.props;
+ const Style = {
+ width: "100%",
+ height: isDesktop ? "445px" : "181.500px",
+ padding: "0px",
+ margin: "0px",
+ };
+
+ switch (type) {
+ case "video/youtube":
+ return (
+ <>
+ VIDEO
+ >
+ );
+
+ default:
+ return (
+ <>
+
+
+ {util.typeCheck(noSupportText, "Your browser does not support HTML video.")}
+
+ >
+ );
+ }
+ }
+}
+
+export default Video;
diff --git a/Website/src/components/icons/Checkmark.tsx b/Website/src/components/icons/Checkmark.tsx
new file mode 100644
index 000000000..9af9fe7c5
--- /dev/null
+++ b/Website/src/components/icons/Checkmark.tsx
@@ -0,0 +1,42 @@
+import ViewX from "@Components/ViewX";
+import { SVGAttributes } from "react";
+
+interface Props {
+ size: string | int;
+ color: `#${string}`;
+ className?: SVGAttributes;
+}
+
+class Checkmark extends ViewX {
+ public static defaultProps: Props;
+
+ public createView() {
+ const { color, size, className } = this.props;
+ return (
+
+
+
+ );
+ }
+}
+
+Checkmark.defaultProps = {
+ size: "14",
+ color: "#1a7f37",
+};
+
+export default Checkmark;
diff --git a/Website/src/components/icons/Dangermark.tsx b/Website/src/components/icons/Dangermark.tsx
new file mode 100644
index 000000000..2274f6298
--- /dev/null
+++ b/Website/src/components/icons/Dangermark.tsx
@@ -0,0 +1,42 @@
+import ViewX from "@Components/ViewX";
+import { SVGAttributes } from "react";
+
+interface Props {
+ size: string | int;
+ color: `#${string}`;
+ className?: SVGAttributes;
+}
+
+class Dankermark extends ViewX {
+ public static defaultProps: Props;
+
+ public createView() {
+ const { color, size, className } = this.props;
+ return (
+
+
+
+ );
+ }
+}
+
+Dankermark.defaultProps = {
+ size: "14",
+ color: "#cf222e",
+};
+
+export default Dankermark;
diff --git a/Website/src/components/icons/Warnmark.tsx b/Website/src/components/icons/Warnmark.tsx
new file mode 100644
index 000000000..df7861da2
--- /dev/null
+++ b/Website/src/components/icons/Warnmark.tsx
@@ -0,0 +1,43 @@
+import ViewX from "@Components/ViewX";
+import { SVGAttributes } from "react";
+
+interface Props {
+ size: string | int;
+ color: `#${string}`;
+ className?: SVGAttributes;
+}
+
+class Warnmark extends ViewX {
+ public static defaultProps: Props;
+
+ public createView() {
+ const { color, size, className } = this.props;
+ return (
+
+
+
+ );
+ }
+}
+
+Warnmark.defaultProps = {
+ size: "14",
+ color: "#d29922",
+};
+
+export default Warnmark;
diff --git a/Website/src/index.tsx b/Website/src/index.tsx
index a6987551f..52949c0e5 100644
--- a/Website/src/index.tsx
+++ b/Website/src/index.tsx
@@ -53,7 +53,7 @@ class Bootloader {
dom.preventer(["contextmenu"]);
this.log.i("Selecting platform: Android");
- this.log.i( );
+ this.log.i(navigator.userAgent);
ons.platform.select("android");
this.loadStyle();
this.loadActivity();
diff --git a/Website/src/language/de.json b/Website/src/language/de.json
index 22b249268..913dd918c 100644
--- a/Website/src/language/de.json
+++ b/Website/src/language/de.json
@@ -5,14 +5,14 @@
"custom_repository": "Eigene repository",
"appearance": "Aussehen",
"language": "Sprache",
- "dark_theme": "Dunkles Design",
+ "dark_theme": "Dunkles Thema",
"bottom_navigation": {
"text": "Navigation unten",
"subtext": "Bewegt Tabs an den unteren Bildschirmrand."
},
"not_supported_in_web_version": "In der Web-Version nicht unterstuetzt",
"source_code": "Quellcode",
- "acknowledgements": "Acknowledgements",
+ "acknowledgements": "Danksagungen/Lizenzen",
"issues": "Issues",
"module_verified": "Dieses Modul ist verifiziert und vertrauenswürdig",
"download": "Herunterladen",
@@ -22,5 +22,18 @@
"remove": "Entfernen",
"restore": "Wiederherstellen",
"module_enabled_LOG": "{module} wurde aktiviert",
- "module_disabled_LOG": "{module} wurde deaktiviert"
+ "module_disabled_LOG": "{module} wurde deaktiviert",
+ "last_updated": "Letztes Update: {date}",
+ "add": "Hinzufügen",
+ "cancel": "Abbrechen",
+ "add_repo": "Repository hinzufügen",
+ "confirm_repo_delete": "Möchten Sie das {name}-Repository wirklich entfernen?",
+ "submit_module": "Ein Module einreichen",
+ "donate": "Spenden",
+ "support": "Support",
+ "website": "Webseite",
+ "no_root": "Kein Root",
+ "failed": "Fehlgeschlagen",
+ "no_root_message": "Scheint, dass keine Root-Berechtigungen vorhanden sind? Wenn Sie Magisk (Delta) installiert haben, können Sie es direkt von hier aus öffnen.",
+ "open_magisk": "Magisk öffnen"
}
diff --git a/Website/src/language/en.json b/Website/src/language/en.json
index 727f954cb..b5d5d3f38 100644
--- a/Website/src/language/en.json
+++ b/Website/src/language/en.json
@@ -22,5 +22,18 @@
"remove": "Remove",
"restore": "Restore",
"module_enabled_LOG": "{module} has been enabled",
- "module_disabled_LOG": "{module} has been disabled"
+ "module_disabled_LOG": "{module} has been disabled",
+ "last_updated": "Last update: {date}",
+ "add": "Add",
+ "cancel": "Cancel",
+ "add_repo": "Add a repository",
+ "confirm_repo_delete": "Are you sure to remove {name} repository?",
+ "submit_module": "Submit a module",
+ "donate": "Donate",
+ "support": "Support",
+ "website": "Website",
+ "no_root": "No Root",
+ "failed": "Failed",
+ "no_root_message": "Seems that you'e doesn't having root permissions? If you have Magisk (Delta) installed you can directly open it from here.",
+ "open_magisk": "Open Magisk"
}
diff --git a/Website/src/native/BuildConfig.ts b/Website/src/native/BuildConfig.ts
index 3a400fbdd..e57f503c2 100644
--- a/Website/src/native/BuildConfig.ts
+++ b/Website/src/native/BuildConfig.ts
@@ -1,5 +1,5 @@
import { os } from "./os";
-import Shell from "@Native/ShellBuilder";
+import Shell from "@Native/Shell";
import pkg from "@Package";
import SharedPreferences from "./SharedPreferences";
import Build from "./Build";
diff --git a/Website/src/native/Constants.ts b/Website/src/native/Constants.ts
deleted file mode 100644
index 26dbdad71..000000000
--- a/Website/src/native/Constants.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-class Constants {
- /**
- * @deprecated
- */
- private static readonly userAgentAndroid = "MMRL";
- /**
- * @deprecated
- */
- public static readonly userAgent = window.navigator.userAgent;
- /**
- * Checks if the app is on Android
- * @deprecated
- */
- public static readonly isAndroid = this.userAgentAndroid === this.userAgent ? true : false;
- /**
- * string, null & undefined
- */
- public static readonly undefined: string | null | undefined = "" || null || undefined;
-
- /**
- * @deprecated
- */
- public static isAndroidIf(_if: any, _else: any) {
- if (this.isAndroid === true) {
- return _if;
- } else {
- return _else;
- }
- }
-}
-
-export default Constants;
diff --git a/Website/src/native/File.ts b/Website/src/native/File.ts
index 191a87475..dbd47d1f1 100644
--- a/Website/src/native/File.ts
+++ b/Website/src/native/File.ts
@@ -1,6 +1,4 @@
-import { util } from "googlers-tools";
-
-export interface IFile {
+export interface FileSystemNative {
read(): string;
list(): string;
exist(): boolean;
@@ -14,30 +12,13 @@ export interface IFile {
download(url: string): void;
}
-export interface IFileStatic {
- new (path?: string | undefined): File;
- read(path: string): string;
- list(path: string): string;
- exist(path: string): boolean;
- delete(path: string): boolean;
- deleteRecursive(path: string): void;
- create(path: string): boolean;
- get getExternalStorageDir(): string;
- get getPackageDataDir(): string;
- getPublicDir(type: string): string;
- get getDataDir(): string;
- download(output: string, path: string): void;
-}
-
declare const nfs: any;
/**
* Class to read files on a native Android device
- * @implements {IFileStatic}
+ * @implements {FileSystemNative}
*/
-
-@util.ImplementsStatics()
-class File {
+class File implements FileSystemNative {
private path: string | undefined;
public constructor(path?: string | undefined) {
@@ -54,7 +35,8 @@ class File {
* new File("").list().split(",");
* ```
*/
- public list(): string {
+ public list(): string;
+ public list(join?: string): string {
return nfs.listFiles(this.path);
}
diff --git a/Website/src/native/Magisk.ts b/Website/src/native/Magisk.ts
index a1e82cf7d..c5f703abd 100644
--- a/Website/src/native/Magisk.ts
+++ b/Website/src/native/Magisk.ts
@@ -1,6 +1,6 @@
import Log from "./Log";
import { os } from "./os";
-import Shell from "./ShellBuilder";
+import Shell from "./Shell";
class Magisk {
private static log: Log = new Log(this.constructor.name);
diff --git a/Website/src/native/Magiskboot.ts b/Website/src/native/Magiskboot.ts
index b6e369ff9..ac9db0dfb 100644
--- a/Website/src/native/Magiskboot.ts
+++ b/Website/src/native/Magiskboot.ts
@@ -1,4 +1,4 @@
-import Shell from "./ShellBuilder";
+import Shell from "./Shell";
class Magiskboot {
public static readonly magiskbootpath: string = "/data/adb/magisk/magiskboot";
diff --git a/Website/src/native/SharedPreferences.ts b/Website/src/native/SharedPreferences.ts
index 276905155..1c770cbea 100644
--- a/Website/src/native/SharedPreferences.ts
+++ b/Website/src/native/SharedPreferences.ts
@@ -5,14 +5,16 @@ export interface ISharedPreferences {
setString(key: string, value: string): void;
setBoolean(key: string, value: bool): void;
setInt(key: string, value: int): void;
+ setJSON(key: string, value: T): void;
getString(key: string, defValue: string): string;
getBoolean(key: string, defValue: boolean): boolean;
getInt(key: string, defValue: int): int;
+ getJSON(key: string, defValue: T): T;
removePref(key: string): void;
clearPrefs(): void;
}
-declare const nsharedpreferences: ISharedPreferences;
+declare const nsharedpreferences: Record any>;
/**
* Simple class to manage the web local sotrage and the Android native preferences
@@ -48,6 +50,14 @@ class SharedPreferences implements ISharedPreferences {
}
}
+ public setJSON(key: string, value: T): void {
+ if (os.isAndroid) {
+ nsharedpreferences.setInt(key, JSON.stringify(value));
+ } else {
+ this.webStorage.setItem(key, JSON.stringify(value));
+ }
+ }
+
/**
* Retrieve a String value from the preferences.
*
@@ -121,6 +131,19 @@ class SharedPreferences implements ISharedPreferences {
}
}
+ public getJSON(key: string, defValue: T): T {
+ if (os.isAndroid) {
+ return JSON.parse(nsharedpreferences.getInt(key, JSON.stringify(defValue)));
+ } else {
+ const get = this.webStorage.getItem(key);
+ if (get === null) {
+ return defValue;
+ } else {
+ return JSON.parse(get);
+ }
+ }
+ }
+
/**
* Removes the key/value pair with the given key, if a key/value pair with the given key exists.
*
@@ -175,7 +198,7 @@ class SharedPreferences implements ISharedPreferences {
*
* @throws ClassCastException
*/
- public static getString(key: string, defValue: string): string | String {
+ public static getString(key: string, defValue: string): string {
return this.s.getString(key, defValue);
}
@@ -191,7 +214,7 @@ class SharedPreferences implements ISharedPreferences {
*
* @throws ClassCastException
*/
- public static getBoolean(key: string, defValue: bool): boolean | Boolean {
+ public static getBoolean(key: string, defValue: bool): boolean {
return this.s.getBoolean(key, defValue);
}
@@ -205,7 +228,7 @@ class SharedPreferences implements ISharedPreferences {
*
* @throws ClassCastException
*/
- public static getInt(key: string, defValue: int): number | Number {
+ public static getInt(key: string, defValue: int): number {
return this.s.getInt(key, defValue);
}
diff --git a/Website/src/native/ShellBuilder.ts b/Website/src/native/Shell.ts
similarity index 56%
rename from Website/src/native/ShellBuilder.ts
rename to Website/src/native/Shell.ts
index eae9bbd95..fbf1ec7f3 100644
--- a/Website/src/native/ShellBuilder.ts
+++ b/Website/src/native/Shell.ts
@@ -1,63 +1,60 @@
import Log from "@Native/Log";
import { os } from "./os";
-interface IShell {
- cmd(cmd: string): this;
+type CMD = Omit;
+
+interface ShellNative {
+ command: string;
+ /**
+ * Runs an Android native shell cmd
+ * Should never used multiple
+ * @return {CMD}
+ */
+ cmd(cmd: string): CMD;
+ /**
+ * Executes an command without result
+ */
exec(): void;
+ /**
+ * Executes an command with result
+ */
result(): string;
isAppGrantedRoot(): boolean;
}
+const Logger = new Log("Shell");
+
/**
* Run Shell commands native on Android
- * @implements {IShell}
*/
-class ShellClass implements IShell {
- private command: string;
- private log: Log;
-
- public constructor() {
- this.log = new Log(this.constructor.name);
- this.command = "";
- }
+type Shell = typeof Shell[keyof typeof Shell];
+const Shell: ShellNative = {
+ command: "",
- /**
- * Runs an Android native shell cmd
- * Should never used multiple
- */
- public cmd(cmd: string): this {
+ cmd(cmd: string): CMD {
this.command = cmd;
return this;
- }
+ },
- /**
- * Executes an command without result
- */
- public exec(): void {
+ exec(): void {
if (os.isAndroid) {
nshell.exec(this.command);
} else {
- this.log.i(this.command);
+ Logger.i(this.command);
}
- }
+ },
- /**
- * Executes an command with result
- */
- public result(): string {
+ result(): string {
if (os.isAndroid) {
return nshell.result(this.command);
} else {
return this.command;
}
- }
+ },
- public isAppGrantedRoot(): boolean {
+ isAppGrantedRoot(): boolean {
return nshell.isAppGrantedRoot();
- }
-}
-
-const Shell: IShell = new ShellClass();
+ },
+} as const;
export default Shell;
-export { ShellClass, IShell };
diff --git a/Website/src/native/Toast.ts b/Website/src/native/Toast.ts
index 65906fcdb..fe892f8f1 100644
--- a/Website/src/native/Toast.ts
+++ b/Website/src/native/Toast.ts
@@ -1,26 +1,53 @@
-import Constants from "@Native/Constants";
import ons from "onsenui";
import { os } from "./os";
-class Toast {
- public static readonly LENGTH_LONG: int = os.isAndroid ? 1 : 5000;
- public static readonly LENGTH_SHORT: int = os.isAndroid ? 0 : 2000;
- private static duration: int;
- private static text: string;
+type ToastReturn = Omit;
- public static makeText(text: string, duration: int): Toast {
+interface IToast {
+ /**
+ * Show the view or text notification for a short period of time.
+ */
+ readonly LENGTH_LONG: int;
+
+ /**
+ * Show the view or text notification for a long period of time.
+ */
+ readonly LENGTH_SHORT: int;
+
+ makeText(text: string, duration: int): ToastReturn;
+ show(): void;
+}
+
+class ToastClass implements IToast {
+ /**
+ * Show the view or text notification for a short period of time.
+ */
+ public readonly LENGTH_LONG: int = os.isAndroid ? 1 : 5000;
+
+ /**
+ * Show the view or text notification for a long period of time.
+ */
+ public readonly LENGTH_SHORT: int = os.isAndroid ? 0 : 2000;
+
+ private duration: int | undefined;
+ private text: string | undefined;
+
+ public makeText(text: string, duration: int): ToastReturn {
this.text = text;
this.duration = duration;
- return new this();
+ return this;
}
public show(): void {
if (os.isAndroid) {
- nos.makeToast(Toast.text, Toast.duration);
+ nos.makeToast(this.text, this.duration);
} else {
- ons.notification.toast(Toast.text, { timeout: Toast.duration, animation: "fall" });
+ ons.notification.toast(this.text, { timeout: this.duration, animation: "fall" });
}
}
}
+const Toast: IToast = new ToastClass();
+
export default Toast;
+export { ToastClass, IToast };
diff --git a/Website/src/native/os.ts b/Website/src/native/os.ts
index a93352edb..47b1158c5 100644
--- a/Website/src/native/os.ts
+++ b/Website/src/native/os.ts
@@ -4,6 +4,7 @@ import SharedPreferences from "./SharedPreferences";
import ons from "onsenui";
import { isValidElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
+import Constants from "@Utils/Constants";
/**
* The `os` module provides operating system-related utility methods and
@@ -14,7 +15,7 @@ import { renderToStaticMarkup } from "react-dom/server";
* ```
*/
class os {
- private static readonly userAgentAndroid = "MMRL";
+ private static readonly userAgentAndroid = Constants.UserAgentAndroid;
public static readonly userAgent = window.navigator.userAgent;
public static readonly isAndroid = this.userAgentAndroid === this.userAgent || window.hasOwnProperty("cordova") ? true : false;
private static readonly android = os.isAndroid;
@@ -105,6 +106,20 @@ class os {
name;
}
}
+
+ public static addNativeEventListener(event: any, callback: any) {
+ // @ts-ignore
+ window[event] = new Event(event.toLowerCase());
+
+ window.addEventListener(event.toLowerCase(), callback, false);
+ }
+
+ public static removeNativeEventListener(event: any, callback: any) {
+ // @ts-ignore
+ window[event] = new Event(event.toLowerCase());
+
+ window.removeEventListener(event.toLowerCase(), callback, false);
+ }
}
export { os };
diff --git a/Website/src/styles/Md3Fab.ts b/Website/src/styles/Md3Fab.ts
new file mode 100644
index 000000000..0028babb0
--- /dev/null
+++ b/Website/src/styles/Md3Fab.ts
@@ -0,0 +1,7 @@
+export function Md3Fab(): any {
+ return {
+ "ons-fab.fab--material3 ": {
+ borderRadius: "30%",
+ },
+ };
+}
diff --git a/Website/src/styles/Md3Switch.ts b/Website/src/styles/Md3Switch.ts
new file mode 100644
index 000000000..1f2bbfc0e
--- /dev/null
+++ b/Website/src/styles/Md3Switch.ts
@@ -0,0 +1,61 @@
+type Color = `#${string}`;
+
+interface Md3SwitchStyles {
+ bgColor: Color;
+ thumbColor: Color;
+ checkedThumbColor: Color;
+ checkedBgColor: Color;
+}
+
+export function Md3Switch(sx: Md3SwitchStyles): any {
+ return {
+ ".switch--material3": {
+ width: "36px",
+ height: "24px",
+ padding: "0 10px",
+ minWidth: "36px",
+ },
+ ".switch--material3__input": {
+ position: "absolute",
+ right: "0",
+ top: "0",
+ left: "0",
+ bottom: "0",
+ padding: "0",
+ border: "0",
+ backgroundColor: "transparent",
+ verticalAlign: "top",
+ outline: "none",
+ width: "100%",
+ height: "100%",
+ margin: "0",
+ webkitAppearance: "none",
+ appearance: "none",
+ zIndex: "0",
+ },
+ ":checked + .switch--material__toggle": {
+ boxShadow: "none",
+ backgroundColor: sx.checkedBgColor,
+ },
+ ".switch--material3__toggle": {
+ backgroundColor: sx.bgColor,
+ marginTop: "2px",
+ height: "20px",
+ boxShadow: "none",
+ },
+ ".switch--material3__handle": {
+ backgroundColor: sx.thumbColor,
+ left: "0",
+ marginTop: "0.3px",
+ width: "15px",
+ height: "15px",
+ boxShadow: "none",
+ marginLeft: "3px",
+ },
+ ":checked + .switch--material3__toggle > .switch--material3__handle": {
+ left: "15px",
+ backgroundColor: sx.checkedThumbColor,
+ boxShadow: "none",
+ },
+ };
+}
diff --git a/Website/src/styles/dark_theme.ts b/Website/src/styles/dark_theme.ts
index 92d217b50..b030692a4 100644
--- a/Website/src/styles/dark_theme.ts
+++ b/Website/src/styles/dark_theme.ts
@@ -1,3 +1,6 @@
+import { Md3Fab } from "./Md3Fab";
+import { Md3Switch } from "./Md3Switch";
+
const dark_theme: any = {
"@global": {
html: {
@@ -340,6 +343,15 @@ const dark_theme: any = {
left: "-15px",
right: "-15px",
},
+
+ // Custom Material 3 Switch and FAB
+ ...Md3Switch({
+ bgColor: "#adacac",
+ thumbColor: "#f1f1f1",
+ checkedThumbColor: "#ffffff",
+ checkedBgColor: "#bb86fc",
+ }),
+
".range": {
display: "inline-block",
position: "relative",
@@ -2398,7 +2410,6 @@ const dark_theme: any = {
},
],
display: "inline-block",
- padding: "0 12px",
height: "100%",
margin: "0",
border: "none",
@@ -4896,6 +4907,10 @@ const dark_theme: any = {
".progress-circular--material__secondary": {
stroke: "rgba(172, 105, 254, 1)",
},
+
+ // Custom Material 3 Fab
+ ...Md3Fab(),
+
"button.fab, ons-fab.fab, ons-speed-dial-item.fab": {
position: "relative",
display: "inline-block",
diff --git a/Website/src/styles/light_theme.ts b/Website/src/styles/light_theme.ts
index 255e78fbe..b2c2bd754 100644
--- a/Website/src/styles/light_theme.ts
+++ b/Website/src/styles/light_theme.ts
@@ -1,3 +1,6 @@
+import { Md3Fab } from "./Md3Fab";
+import { Md3Switch } from "./Md3Switch";
+
const light_theme: any = {
"@global": {
":root": {},
@@ -18,14 +21,14 @@ const light_theme: any = {
touchAction: "manipulation",
},
"html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video":
- {
- webkitUserSelect: "none",
- mozUserSelect: "none",
- msUserSelect: "none",
- userSelect: "none",
- webkitTapHighlightColor: "transparent",
- webkitTouchCallout: "none",
- },
+ {
+ webkitUserSelect: "none",
+ mozUserSelect: "none",
+ msUserSelect: "none",
+ userSelect: "none",
+ webkitTapHighlightColor: "transparent",
+ webkitTouchCallout: "none",
+ },
"input, textarea, select": {
webkitUserSelect: "auto",
msUserSelect: "auto",
@@ -157,18 +160,18 @@ const light_theme: any = {
fontSize: "20px",
},
".page--material__content h1, .page--material__content h2, .page--material__content h3, .page--material__content h4, .page--material__content h5":
- {
- fontFamily: '"Roboto", "Noto", sans-serif',
- webkitFontSmoothing: "antialiased",
- fontWeight: "500",
- fallbacks: [
- {
- fontWeight: "400",
- },
- ],
- margin: "0.6em 0",
- padding: "0",
- },
+ {
+ fontFamily: '"Roboto", "Noto", sans-serif',
+ webkitFontSmoothing: "antialiased",
+ fontWeight: "500",
+ fallbacks: [
+ {
+ fontWeight: "400",
+ },
+ ],
+ margin: "0.6em 0",
+ padding: "0",
+ },
".page--material__content h1": {
fontSize: "28px",
},
@@ -319,8 +322,7 @@ const light_theme: any = {
marginTop: "-5px",
width: "20px",
height: "20px",
- boxShadow:
- "0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12),\r\n 0 2px 4px -1px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12),\r\n 0 2px 4px -1px rgba(0, 0, 0, 0.4)",
},
":checked + .switch--material__toggle": {
backgroundColor: "#7c43bd",
@@ -329,8 +331,7 @@ const light_theme: any = {
":checked + .switch--material__toggle > .switch--material__handle": {
left: "16px",
backgroundColor: "#4a148c",
- boxShadow:
- "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
+ boxShadow: "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
},
":disabled + .switch--material__toggle": {
opacity: "0.3",
@@ -360,6 +361,15 @@ const light_theme: any = {
left: "-15px",
right: "-15px",
},
+
+ // Custom Material 3 Switch and FAB
+ ...Md3Switch({
+ bgColor: "#b0afaf",
+ thumbColor: "#f1f1f1",
+ checkedThumbColor: "#ffffff",
+ checkedBgColor: "#4a148c",
+ }),
+
".range": {
display: "inline-block",
position: "relative",
@@ -581,8 +591,7 @@ const light_theme: any = {
"-moz-radial-gradient(\r\n circle farthest-corner,\r\n #4a148c 0%,\r\n #4a148c 6.6px,\r\n transparent 7px\r\n )",
boxShadow: "none",
},
- ".range--material__input:active::-webkit-slider-thumb, .range--material__input.range__input--active::-webkit-slider-thumb":
- {
+ ".range--material__input:active::-webkit-slider-thumb, .range--material__input.range__input--active::-webkit-slider-thumb": {
webkitTransform: "scale(1.5)",
transform: "scale(1.5)",
transition: "transform 0.1s linear, -webkit-transform 0.1s linear",
@@ -796,8 +805,7 @@ const light_theme: any = {
".list-item--material.list-item--expandable": {
backgroundImage: "linear-gradient(0deg, #eee, #eee 50%, transparent 50%)",
},
- ".list-item--material.list-item--longdivider, .list-item--material.list-item--expandable.list-item--longdivider":
- {
+ ".list-item--material.list-item--longdivider, .list-item--material.list-item--expandable.list-item--longdivider": {
backgroundImage: "linear-gradient(0deg, #eee, #eee 50%, transparent 50%)",
},
".list-header--material:not(:first-of-type)": {
@@ -1633,8 +1641,7 @@ const light_theme: any = {
backgroundColor: "#4a148c",
borderRadius: "8px",
transition: "all 0.25s linear",
- boxShadow:
- "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
+ boxShadow: "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
minHeight: "36px",
textAlign: "center",
webkitTransform: "translate3d(0, 0, 0)",
@@ -1646,8 +1653,7 @@ const light_theme: any = {
transition: "all 0.25s linear",
},
".button--material:active": {
- boxShadow:
- "0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 5px -1px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 5px -1px rgba(0, 0, 0, 0.4)",
backgroundColor: "#4a148c",
opacity: "0.9",
transition: "all 0.25s linear",
@@ -1698,8 +1704,7 @@ const light_theme: any = {
backgroundColor: "#4a148c",
},
{
- boxShadow:
- "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
+ boxShadow: "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
},
{
transition: "none",
@@ -2032,8 +2037,7 @@ const light_theme: any = {
borderRadius: "0",
borderWidth: "0",
},
- ".segment--material__item:first-child > .segment--material__button, .segment--material__item:last-child > .segment--material__button":
- {
+ ".segment--material__item:first-child > .segment--material__button, .segment--material__item:last-child > .segment--material__button": {
borderRadius: "0",
borderWidth: "0",
},
@@ -2250,8 +2254,7 @@ const light_theme: any = {
background: "none",
backgroundColor: "#4a148c",
borderBottomWidth: "0",
- boxShadow:
- "0 4px 2px -2px rgba(0, 0, 0, 0.14), 0 3px 5px -2px rgba(0, 0, 0, 0.12),\r\n 0 5px 1px -4px rgba(0, 0, 0, 0.2)",
+ boxShadow: "0 4px 2px -2px rgba(0, 0, 0, 0.14), 0 3px 5px -2px rgba(0, 0, 0, 0.12),\r\n 0 5px 1px -4px rgba(0, 0, 0, 0.2)",
},
".tabbar--material__button": {
backgroundColor: "transparent",
@@ -3439,10 +3442,10 @@ const light_theme: any = {
paddingRight: "30px",
},
".list-item--nodivider__center, .list-item--nodivider__right, .list-item--nodivider.list-item--expandable, .list-item--expandable .list-item__center, .list-item--expandable .list-item__right":
- {
- border: "none",
- backgroundImage: "none",
- },
+ {
+ border: "none",
+ backgroundImage: "none",
+ },
".list-item--longdivider": {
borderBottom: "none",
fallbacks: [
@@ -3627,8 +3630,7 @@ const light_theme: any = {
backgroundPosition: "18px center",
fontSize: "14px",
padding: "0 24px 0 64px",
- boxShadow:
- "0 0 2px 0 rgba(0, 0, 0, 0.12), 0 2px 2px 0 rgba(0, 0, 0, 0.24),\r\n 0 1px 0 0 rgba(255, 255, 255, 0.06) inset",
+ boxShadow: "0 0 2px 0 rgba(0, 0, 0, 0.12), 0 2px 2px 0 rgba(0, 0, 0, 0.24),\r\n 0 1px 0 0 rgba(255, 255, 255, 0.06) inset",
},
".text-input": {
boxSizing: "border-box",
@@ -3924,8 +3926,7 @@ const light_theme: any = {
],
},
".text-input--material:focus": {
- backgroundImage:
- "linear-gradient(#3d5afe, #3d5afe),\r\n linear-gradient(to top, transparent 1px, #afafaf 1px)",
+ backgroundImage: "linear-gradient(#3d5afe, #3d5afe),\r\n linear-gradient(to top, transparent 1px, #afafaf 1px)",
webkitAnimation: "material-text-input-animate 0.3s forwards",
animation: "material-text-input-animate 0.3s forwards",
},
@@ -4144,8 +4145,7 @@ const light_theme: any = {
webkitFontSmoothing: "antialiased",
fontWeight: "400",
textAlign: "left",
- boxShadow:
- "0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12),\r\n 0 8px 10px -5px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12),\r\n 0 8px 10px -5px rgba(0, 0, 0, 0.4)",
},
".dialog-container--material": {
borderRadius: "8px",
@@ -4340,14 +4340,13 @@ const light_theme: any = {
],
},
".alert-dialog--material": {
- borderRadius: "8px",
+ borderRadius: "25px",
backgroundColor: "#ffffff",
},
".alert-dialog-container--material": {
- borderRadius: "8px",
+ borderRadius: "25px",
padding: "22px 0 0 0",
- boxShadow:
- "0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12),\r\n 0 8px 10px -5px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12),\r\n 0 8px 10px -5px rgba(0, 0, 0, 0.4)",
},
".alert-dialog-title--material": {
fontFamily: '"Roboto", "Noto", sans-serif',
@@ -4549,8 +4548,7 @@ const light_theme: any = {
backgroundColor: "#fafafa",
borderRadius: "2px",
color: "#1f1f21",
- boxShadow:
- "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
+ boxShadow: "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
},
".popover--material__arrow": {
display: "none",
@@ -4718,8 +4716,7 @@ const light_theme: any = {
strokeDashoffset: "-251.32%",
},
},
- ".progress-circular--material__background, .progress-circular--material__primary, .progress-circular--material__secondary":
- {
+ ".progress-circular--material__background, .progress-circular--material__primary, .progress-circular--material__secondary": {
strokeWidth: "9%",
},
".progress-circular--material__background": {
@@ -4731,6 +4728,10 @@ const light_theme: any = {
".progress-circular--material__secondary": {
stroke: "#12005e",
},
+
+ // Custom Material 3 Fab
+ ...Md3Fab(),
+
"ons-fab.fab, ons-speed-dial-item.fab, button.fab": {
position: "relative",
display: "inline-block",
@@ -4770,7 +4771,7 @@ const light_theme: any = {
verticalAlign: "middle",
textAlign: "center",
backgroundColor: "#4a148c",
- borderRadius: "50%",
+ borderRadius: "30%",
overflow: "hidden",
boxShadow: "0 3px 6px rgba(0, 0, 0, 0.12)",
transition: "all 0.1s linear",
@@ -4789,12 +4790,12 @@ const light_theme: any = {
outline: "0",
},
"ons-fab.fab:disabled, ons-fab.fab[disabled], ons-speed-dial-item.fab:disabled, ons-speed-dial-item.fab[disabled], button.fab:disabled, button.fab[disabled]":
- {
- backgroundColor: "color-mod(black alpha(50%))",
- boxShadow: "none",
- opacity: "0.3",
- pointerEvents: "none",
- },
+ {
+ backgroundColor: "color-mod(black alpha(50%))",
+ boxShadow: "none",
+ opacity: "0.3",
+ pointerEvents: "none",
+ },
"ons-fab.fab__icon, ons-speed-dial-item.fab__icon, button.fab__icon": {
position: "relative",
overflow: "hidden",
@@ -4886,13 +4887,11 @@ const light_theme: any = {
backgroundColor: "#4a148c",
borderRadius: "50%",
overflow: "hidden",
- boxShadow:
- "0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12),\r\n 0 2px 4px -1px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12),\r\n 0 2px 4px -1px rgba(0, 0, 0, 0.4)",
transition: "all 0.2s ease-in-out",
},
"ons-fab.fab--material:active, ons-speed-dial-item.fab--material:active, button.fab--material:active": {
- boxShadow:
- "0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12),\r\n 0 5px 5px -3px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12),\r\n 0 5px 5px -3px rgba(0, 0, 0, 0.4)",
backgroundColor: "rgba(255, 255, 255, 0.75)",
fallbacks: [
{
@@ -4916,12 +4915,12 @@ const light_theme: any = {
lineHeight: "56px",
},
"ons-fab.fab--material:disabled, ons-fab.fab--material[disabled], ons-speed-dial-item.fab--material:disabled, ons-speed-dial-item.fab--material[disabled], button.fab--material:disabled, button.fab--material[disabled]":
- {
- backgroundColor: "color-mod(black alpha(50%))",
- boxShadow: "none",
- opacity: "0.3",
- pointerEvents: "none",
- },
+ {
+ backgroundColor: "color-mod(black alpha(50%))",
+ boxShadow: "none",
+ opacity: "0.3",
+ pointerEvents: "none",
+ },
"ons-fab.fab--mini, ons-speed-dial-item.fab--mini, button.fab--mini": {
width: "40px",
height: "40px",
@@ -5455,8 +5454,7 @@ const light_theme: any = {
left: "0",
right: "0",
bottom: "0",
- boxShadow:
- "0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12),\r\n 0 8px 10px -5px rgba(0, 0, 0, 0.4)",
+ boxShadow: "0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12),\r\n 0 8px 10px -5px rgba(0, 0, 0, 0.4)",
},
".action-sheet-title--material": {
fontFamily: '"Roboto", "Noto", sans-serif',
@@ -5568,8 +5566,7 @@ const light_theme: any = {
".card--material": {
backgroundColor: "white",
borderRadius: "8px",
- boxShadow:
- "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
+ boxShadow: "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),\r\n 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
fontFamily: '"Roboto", "Noto", sans-serif',
webkitFontSmoothing: "antialiased",
fontWeight: "400",
@@ -5697,15 +5694,15 @@ const light_theme: any = {
top: "0",
},
".toolbar.toolbar--transparent.toolbar--cover-content + .page__background + .page__content, .toolbar.toolbar--transparent.toolbar--cover-content\r\n + .page__background\r\n + .page__content\r\n .page_content":
- {
- top: "0",
- paddingTop: "44px",
- },
+ {
+ top: "0",
+ paddingTop: "44px",
+ },
".toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content\r\n + .page__background\r\n + .page__content, .toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content\r\n + .page__background\r\n + .page__content\r\n .page_content":
- {
- top: "0",
- paddingTop: "56px",
- },
+ {
+ top: "0",
+ paddingTop: "56px",
+ },
".tabbar:not(.tabbar--top)": {
paddingBottom: "0",
},
@@ -5739,9 +5736,9 @@ const light_theme: any = {
width: "calc(100% - 88px)",
},
"html[onsflag-iphonex-landscape] .fab--bottom__left, html[onsflag-iphonex-landscape] .fab--bottom__center, html[onsflag-iphonex-landscape] .fab--bottom__right":
- {
- bottom: "21px",
- },
+ {
+ bottom: "21px",
+ },
"html[onsflag-iphonex-landscape] .fab--top__left, html[onsflag-iphonex-landscape] .fab--bottom__left": {
left: "44px",
},
@@ -5759,39 +5756,39 @@ const light_theme: any = {
bottom: "21px",
},
"html[onsflag-iphonex-landscape] .dialog .bottom-bar, html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content .bottom-bar, html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .bottom-bar":
- {
- bottom: "0",
- boxSizing: "border-box",
- paddingBottom: "0",
- },
+ {
+ bottom: "0",
+ boxSizing: "border-box",
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-landscape] .dialog .page__content, html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content .page__content, html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page__content, html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content":
- {
- bottom: "0",
- paddingBottom: "0",
- },
+ {
+ bottom: "0",
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content": {
bottom: "65px",
paddingBottom: "0",
},
"html[onsflag-iphonex-landscape] .dialog .page-with-bottom-toolbar > .page__content, html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content .page-with-bottom-toolbar > .page__content, html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar > .page__content":
- {
- bottom: "44px",
- paddingBottom: "0",
- },
+ {
+ bottom: "44px",
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-landscape] .tabbar:not(.tabbar--top)": {
paddingBottom: "21px",
},
"html[onsflag-iphonex-landscape] .dialog .tabbar:not(.tabbar--top), html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content .tabbar:not(.tabbar--top), html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top)":
- {
- paddingBottom: "0",
- },
+ {
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content)": {
bottom: "70px",
},
"html[onsflag-iphonex-landscape] .dialog .tabbar__content:not(.tabbar--top__content), html[onsflag-iphonex-landscape] .page-with-bottom-toolbar > .page__content .tabbar__content:not(.tabbar--top__content), html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content)":
- {
- bottom: "49px",
- },
+ {
+ bottom: "49px",
+ },
"html[onsflag-iphonex-landscape] .page__content > .list:not(.list--inset)": {
marginLeft: "-44px",
marginRight: "-44px",
@@ -5802,22 +5799,21 @@ const light_theme: any = {
"html[onsflag-iphonex-landscape] .page__content > .list:not(.list--inset) > .list-item": {
paddingLeft: "58px",
},
- "html[onsflag-iphonex-landscape]\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item--chevron:before":
- {
+ "html[onsflag-iphonex-landscape]\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item--chevron:before": {
right: "60px",
},
"html[onsflag-iphonex-landscape]\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item\r\n > .list-item__center:last-child":
- {
- paddingRight: "50px",
- },
+ {
+ paddingRight: "50px",
+ },
"html[onsflag-iphonex-landscape]\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item\r\n > .list-item__right":
- {
- paddingRight: "56px",
- },
+ {
+ paddingRight: "56px",
+ },
"html[onsflag-iphonex-landscape]\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item\r\n > .list-item--chevron__right":
- {
- paddingRight: "74px",
- },
+ {
+ paddingRight: "74px",
+ },
"html[onsflag-iphonex-landscape] .dialog .page__content > .list:not(.list--inset)": {
marginLeft: "0",
marginRight: "0",
@@ -5829,31 +5825,31 @@ const light_theme: any = {
paddingLeft: "14px",
},
"html[onsflag-iphonex-landscape]\r\n .dialog\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item--chevron:before":
- {
- right: "16px",
- },
+ {
+ right: "16px",
+ },
"html[onsflag-iphonex-landscape]\r\n .dialog\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item\r\n > .list-item__center:last-child":
- {
- paddingRight: "6px",
- },
+ {
+ paddingRight: "6px",
+ },
"html[onsflag-iphonex-landscape]\r\n .dialog\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item\r\n > .list-item__right":
- {
- paddingRight: "12px",
- },
+ {
+ paddingRight: "12px",
+ },
"html[onsflag-iphonex-landscape]\r\n .dialog\r\n .page__content\r\n > .list:not(.list--inset)\r\n > .list-item\r\n > .list-item--chevron__right":
- {
- paddingRight: "30px",
- },
+ {
+ paddingRight: "30px",
+ },
},
"@media (orientation: portrait)": {
"html[onsflag-iphonex-portrait] .fab--top__left, html[onsflag-iphonex-portrait] .fab--top__center, html[onsflag-iphonex-portrait] .fab--top__right":
- {
- top: "64px",
- },
+ {
+ top: "64px",
+ },
"html[onsflag-iphonex-portrait] .fab--bottom__left, html[onsflag-iphonex-portrait] .fab--bottom__center, html[onsflag-iphonex-portrait] .fab--bottom__right":
- {
- bottom: "34px",
- },
+ {
+ bottom: "34px",
+ },
"html[onsflag-iphonex-portrait] .action-sheet": {
bottom: "48px",
},
@@ -5866,22 +5862,22 @@ const light_theme: any = {
paddingTop: "44px",
},
"html[onsflag-iphonex-portrait] .dialog .toolbar, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar, html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar":
- {
- top: "0",
- boxSizing: "border-box",
- paddingTop: "0",
- },
+ {
+ top: "0",
+ boxSizing: "border-box",
+ paddingTop: "0",
+ },
"html[onsflag-iphonex-portrait] .bottom-bar": {
bottom: "0",
boxSizing: "content-box",
paddingBottom: "34px",
},
"html[onsflag-iphonex-portrait] .dialog .bottom-bar, html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content .bottom-bar, html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .bottom-bar":
- {
- bottom: "0",
- boxSizing: "border-box",
- paddingBottom: "0",
- },
+ {
+ bottom: "0",
+ boxSizing: "border-box",
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-portrait] .page__content": {
top: "0",
paddingTop: "44px",
@@ -5889,72 +5885,72 @@ const light_theme: any = {
paddingBottom: "34px",
},
"html[onsflag-iphonex-portrait] .dialog .page__content, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .page__content, html[onsflag-iphonex-portrait] .tabbar--top__content .page__content, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content":
- {
- top: "0",
- paddingTop: "0",
- },
+ {
+ top: "0",
+ paddingTop: "0",
+ },
"html[onsflag-iphonex-portrait] .dialog .page__content, html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content .page__content, html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page__content, html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content":
- {
- bottom: "0",
- paddingBottom: "0",
- },
+ {
+ bottom: "0",
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content) + .page__background, html[onsflag-iphonex-portrait]\r\n .toolbar:not(.toolbar--cover-content)\r\n + .page__background\r\n + .page__content":
- {
- top: "88px",
- paddingTop: "0",
- },
+ {
+ top: "88px",
+ paddingTop: "0",
+ },
"html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background, html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background+.page__content, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content, html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background, html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content":
- {
- top: "44px",
- paddingTop: "0",
- },
+ {
+ top: "44px",
+ paddingTop: "0",
+ },
"html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content": {
bottom: "78px",
paddingBottom: "0",
},
"html[onsflag-iphonex-portrait] .dialog .page-with-bottom-toolbar > .page__content, html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content .page-with-bottom-toolbar > .page__content, html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar > .page__content":
- {
- bottom: "44px",
- paddingBottom: "0",
- },
+ {
+ bottom: "44px",
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-portrait]\r\n .toolbar.toolbar--transparent.toolbar--cover-content\r\n + .page__background\r\n + .page__content, html[onsflag-iphonex-portrait]\r\n .toolbar.toolbar--transparent.toolbar--cover-content\r\n + .page__background\r\n + .page__content\r\n .page_content":
- {
- top: "0",
- paddingTop: "88px",
- },
+ {
+ top: "0",
+ paddingTop: "88px",
+ },
"html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content, html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page__content, html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content, html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content":
- {
- top: "0",
- paddingTop: "44px",
- },
+ {
+ top: "0",
+ paddingTop: "44px",
+ },
"html[onsflag-iphonex-portrait] .tabbar--top": {
paddingTop: "44px",
},
"html[onsflag-iphonex-portrait] .dialog .tabbar--top, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top, html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top":
- {
- paddingTop: "0",
- },
+ {
+ paddingTop: "0",
+ },
"html[onsflag-iphonex-portrait] .tabbar--top__content": {
top: "93px",
},
"html[onsflag-iphonex-portrait] .dialog .tabbar--top__content, html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top__content, html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top__content":
- {
- top: "49px",
- },
+ {
+ top: "49px",
+ },
"html[onsflag-iphonex-portrait] .tabbar:not(.tabbar--top):not(.tabbar--top)": {
paddingBottom: "34px",
},
"html[onsflag-iphonex-portrait] .dialog .tabbar:not(.tabbar--top):not(.tabbar--top), html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content .tabbar:not(.tabbar--top), html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top)":
- {
- paddingBottom: "0",
- },
+ {
+ paddingBottom: "0",
+ },
"html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content)": {
bottom: "83px",
},
"html[onsflag-iphonex-portrait] .dialog .tabbar__content:not(.tabbar--top__content), html[onsflag-iphonex-portrait] .page-with-bottom-toolbar > .page__content .tabbar__content:not(.tabbar--top__content), html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content)":
- {
- bottom: "49px",
- },
+ {
+ bottom: "49px",
+ },
},
},
};
diff --git a/Website/src/typings/ModuleProps.ts b/Website/src/typings/ModuleProps.ts
new file mode 100644
index 000000000..89bbe0276
--- /dev/null
+++ b/Website/src/typings/ModuleProps.ts
@@ -0,0 +1,32 @@
+namespace ModuleProps {
+ export interface FoxProps {
+ minApi?: int;
+ maxApi?: int
+ minMagisk?: string | int;
+ needRamdisk?: boolean;
+ support?: string;
+ donate?: string;
+ config?: string;
+ changeBoot?: boolean;
+ }
+
+ export interface PropUrl {
+ id: string;
+ name: string;
+ author: string;
+ version: string;
+ versionCode: string;
+ description: string;
+ foxprops: FoxProps;
+ }
+
+ export interface RootObject {
+ id: string;
+ last_update: number;
+ zip_url: string;
+ notes_url: string;
+ prop_url: PropUrl;
+ }
+}
+
+export default ModuleProps;
diff --git a/Website/src/typings/android/os.d.ts b/Website/src/typings/android/os.d.ts
index 87b801eb2..4b493e1fe 100644
--- a/Website/src/typings/android/os.d.ts
+++ b/Website/src/typings/android/os.d.ts
@@ -1,5 +1,5 @@
interface NOS {
- makeToast(content: string, duration: int): void;
+ makeToast(content: string | undefined, duration: int| undefined): void;
getSchemeParam(param: string): string;
hasStoragePermission(): bool;
requestStoargePermission(): void;
diff --git a/Website/src/typings/declaration.d.ts b/Website/src/typings/declaration.d.ts
index 2b4679bcf..b300f3fb2 100644
--- a/Website/src/typings/declaration.d.ts
+++ b/Website/src/typings/declaration.d.ts
@@ -244,6 +244,7 @@ declare module "react-onsenui" {
/*** AlertDialog ***/
export class AlertDialog extends Component<
{
+ children: React.ReactNode;
onCancel?(): void;
isOpen?: boolean | undefined;
isCancelable?: boolean | undefined;
@@ -303,7 +304,8 @@ declare module "react-onsenui" {
export class Popover extends Component<
{
- getTarget?(): React.ReactInstance;
+ children?: React.ReactNode;
+ getTarget?(): /*React.ReactInstance |*/ any;
onCancel?(): void;
isOpen?: boolean | undefined;
isCancelable?: boolean | undefined;
@@ -313,6 +315,8 @@ declare module "react-onsenui" {
maskColor?: string | undefined;
animationOptions?: AnimationOptions | undefined;
onPreShow?(): void;
+ onOpen?(): void;
+ onHide?(): void;
onPostShow?(): void;
onPreHide?(): void;
onPostHide?(): void;
@@ -584,6 +588,7 @@ declare module "react-onsenui" {
export class ListHeader extends Component<
{
+ children?: React.ReactNode;
modifier?: string | undefined;
},
any
@@ -605,7 +610,7 @@ declare module "react-onsenui" {
export class ListTitle extends Component<
{
- children: string;
+ children: React.ReactNode;
modifier?: string | undefined;
onClick?: React.MouseEventHandler | undefined;
},
@@ -629,6 +634,7 @@ declare module "react-onsenui" {
/** Pull-to-refresh hook. */
export class PullHook extends Component<
{
+ children: string;
onChange?(e: PullHookChangeEvent): void;
onLoad?(done: () => void): void;
onPull?(): void;
@@ -650,6 +656,33 @@ declare module "react-onsenui" {
any
> {}
+ export class GestureDetector extends Component<
+ {
+ children?: React.ReactNode;
+ onDrag?(): void;
+ onDragLeft?(): void;
+ onDragRight?(): void;
+ onDragUp?(): void;
+ onDragDown?(): void;
+ onHold?(): void;
+ onRelease?(): void;
+ onSwipe?(): void;
+ onSwipeLeft?(): void;
+ onSwipeRight?(): void;
+ onSwipeUp?(): void;
+ onSwipeDown?(): void;
+ onTap?(): void;
+ onDoubleTap?(): void;
+ onPinch?(): void;
+ onPinchIn?(): void;
+ onPinchOut?(): void;
+ onTouch?(): void;
+ onTransform?(): void;
+ onRotate?(): void;
+ },
+ any
+ > {}
+
export type SpeedDialPosition = "top" | "right" | "bottom" | "left" | "top right" | "top left" | "bottom right" | "bottom left";
export type SpeedDialDirection = "up" | "down" | "left" | "right";
diff --git a/Website/src/typings/global.d.ts b/Website/src/typings/global.d.ts
index e601b694a..ea7a7929e 100644
--- a/Website/src/typings/global.d.ts
+++ b/Website/src/typings/global.d.ts
@@ -16,6 +16,7 @@ declare global {
}
interface Window {
+ [x: string]: any;
nshell: NShell;
nos: NOS;
nversion: NBuildConfig;
diff --git a/Website/src/utils/Constants.ts b/Website/src/utils/Constants.ts
new file mode 100644
index 000000000..0ec294cc8
--- /dev/null
+++ b/Website/src/utils/Constants.ts
@@ -0,0 +1,6 @@
+enum Constants {
+ UserAgentAndroid = "MMRL",
+ GlobalMMRLTitle = "Magisk Module Repo Loader",
+}
+
+export default Constants;
diff --git a/Website/src/utils/licenses.json b/Website/src/utils/licenses.json
index ca6c8665b..ce21ba69c 100644
--- a/Website/src/utils/licenses.json
+++ b/Website/src/utils/licenses.json
@@ -1,170 +1,186 @@
[
{
- "name": "œ€æ≠│3µ∑│24≥┌βæ┤±3œ=",
- "description": "æ€┤α┌β÷├─¢«├│β8├¿€æ↓±3š∑┌Ÿµ∑│24=",
- "author": "µÆ1≥┐€α≥│┬↕⁄│250┌βα┬┐¢µ≥┌γ«=",
- "version": "«×‰≤¥¶4↓",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√שβ┤œž↓1↓±•«α¿├↔7¥∫¿│/€÷4Δœ∫9§αš→←5æœ+→6│€∑«α±┼↔«±0┬┬→≈µ1┼↔÷→Æ↓≥6®∫┬├+→•→¶↑§™«9"
+ "name": "@emotion/react",
+ "description": "There is no description",
+ "author": "Emotion Contributors",
+ "version": "11.9.3",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/@emotion/react"
},
- {
- "name": "œ€æ≠│3µ∑│24≥┌3µ5│€æ┼",
- "description": "┌3µ5│€æ┼ž‰™œ¶¶↕β│3ž├¿Æ1≥┐€α≥│├==",
- "author": "│γæ≈│↔==",
- "version": "«×‰≤¥¶4↓",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√שβ┤œž↓1↓±•«α¿├↔7¥∫¿│/€÷4Δœ∫9§αš→←5æœ+→6│€∑«α±┼↔«±0┬┬→≈µ1┼↔÷→Æ↓≥6®∫┬├←↓≠æΔ•∫œ≈8"
+ {
+ "name": "@emotion/styled",
+ "description": "styled API for emotion",
+ "author": "null",
+ "version": "11.9.3",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/@emotion/styled"
},
- {
- "name": "œ€∑↓©γ↕→│3↕α┌γµ∑¿¢«≥┌Ÿš≥┌€æ→┐€αα┌←==",
- "description": "¶β™2±æ§┴┌βα←┐•↔≤┌Ÿš≥┌€æ→┐€αα┌→↕←±¢š↓¿¢ž├±Æ5┼žŸ§0┌βα≤¿2αβ─Ææ→",
- "author": "┌€™≈│Ÿ┤∫ž⁄↑γ─¢µΔ┐Æš↔┌€™≈│Ÿ┤∫©β§≥│×4=",
- "version": "«•41©┴œ=",
- "license": "×÷α÷",
- "repository": "↔7¥γ≠œ+→Æ∑•/Δ2‰←↔«│β┼6┼↓≠∫┌•æš┬↑⁄7¥1‰│+┬√↓0="
+ {
+ "name": "@js.properties/properties",
+ "description": "JavaScript .properties parser and stringifier",
+ "author": "pallxk ",
+ "version": "0.5.4",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/@js.properties/properties"
},
- {
- "name": "œ€11─¶9∑±29≤┌→1≠±¢µα┌βα┤│↔==",
- "description": "ׯ™0¿¢š∑±Æ←├µ€æ↓─Æ┐≤ž€α┴│25↓ž€µ∑┌3µ→─Æš1┐€æ┼ž€™↓ž™§Æµ→↕¶¿Æ™┴┐•↕┴│21←│25α│γµ↓©├==",
- "author": "×ææšž™µα±Æ0=",
- "version": "§¶44©┴œ=",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√מ↑æ├•2Æ2•↑Δ∫┬↑⁄7Æ↑¶¶ž┬«æ±↔≠┴┬↓↔®§×Øœ=="
+ {
+ "name": "@mui/icons-material",
+ "description": "Material Design icons distributed as SVG React components.",
+ "author": "MUI Team",
+ "version": "5.8.4",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/@mui/icons-material"
},
- {
- "name": "œ€11─¶9≠±¢µα┌βα┤│↔==",
- "description": "÷βæ┤±3œ├±29≠┌€9≤¿Æ50┌→↕0─€™0ž€α≠┌€↑α│Ææ≤┐•↕Ÿ│29γ│€÷γ┌→↕§±¢µα┌βα┤│•↕‰¿¢§∑¿24≤",
- "author": "×ææšž™µα±Æ0=",
- "version": "§¶44©┴┌=",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√מ↑æ├•2Æ2•↑Δ∫┬↑⁄7Æ↑¶¶ž┬«æ±↔≠┴┬↓↔®§×Øœ=="
+ {
+ "name": "@mui/material",
+ "description": "React components that implement Google's Material Design.",
+ "author": "MUI Team",
+ "version": "5.8.7",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/@mui/material"
},
- {
- "name": "±¢┤∑│3«=",
- "description": "÷Ÿš≥│Æα↓¿¶↕┬±¢§α¿•↕žæ™µœž€§≈─Ææ≤┐•↕β│3ž├┐€┤αž€š→│3┐↓¿¢ž├±Æ5┼ž€5≥¿€÷≤─γ«=",
- "author": "ׯ™0┐•↕─±Æš→─¢§∫─Æ÷=",
- "version": "«•4→§→4→",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√æ«┬Æœ⁄€Æ∑¥∑÷→ž0↔«±5┼6→→«┴±œα⁄09"
+ {
+ "name": "axios",
+ "description": "Promise based HTTP client for the browser and node.js",
+ "author": "Matt Zabriskie",
+ "version": "0.27.2",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/axios"
},
- {
- "name": "±β90±×±0",
- "description": "¶¢œγ┌→↕≠└¶↕β─¢š↓┐•↕┴┐¢§0│20├¿Æ5┴│2µ∑│β┌├¥┬├=",
- "author": "µ€æ→¢0┐≥│2┐≈¿¢ž├ØŸ§1┌Ÿ↕≥┌γµ↔¿€æ→¿29≥¿2↑α┌┬5┴│20+",
- "version": "«¶4←©┴┌=",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√ו11┴‰8«ΔΔ•æ↓šž≥6§+¿α─→¥×•↑17‰←"
+ {
+ "name": "bota64",
+ "description": "It's my first custom encoding :(",
+ "author": "Der_Googler ",
+ "version": "1.0.7",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/bota64"
},
- {
- "name": "¿29≥¿2↑α┌γ«≠┐€9≥│Ÿ«=",
- "description": "×¢┼├│3┐≤žŸµ≥│2↑↓ž•8├┌2§→─¢↕0┌→↕0─€™0ž€┼├┐¢§α©├==",
- "author": "µ€æ→¢0┐≥│2┐≈¿¢ž├Ø€∑∑│Æ15±β9α─€1↔¿€æ→¿29≥¿2↑α┌┬5┴│20+",
- "version": "«¶4→©┴÷=",
- "license": "µ1↕«©×«≤«↔==",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√ו11┴‰8«ΔΔ•æ↓šž≥6§+¿│8→Æ2Æ/÷5¶↑⁄7¥∫┤ו≈Æ4Δ•└®≈9"
- },
- {
- "name": "─γ§↓",
- "description": "œ¶↕≈─Æž├¿β9→ž€┐α│βæ→±¢µ∑│β┌├÷3µ5│€÷├÷2┤α¿¢µ↓žŸ┐∑┐€├├¶β™2±æ§┴┌βα←┐•4=",
- "author": "¶α§×ž™µα±Æ0=",
- "version": "«×↔≤¥¶4←",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×®γ≤↔←→04┼↔≈81α↔7¥γ←=="
- },
- {
- "name": "─γ§↓©¢↕→¿¢§α┐•1┼¿Æ¿┤┐Æ↑0",
- "description": "µ€æβ±¢æ≈┐•↕←┌βæ↓¿¢œ├¿β9→ž‰∑×÷→↕3─¢µΔžŸ§α│€æ┴┐€æ┼žŸ↕≈┐Æ┐∑│γ«≤",
- "author": "¶α§×ž™µα±Æ0=",
- "version": "«×↔≤¥¶4←",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×®γ≤↔←→04┼↔≈81α↔7¥γ←=="
- },
- {
- "name": "│€9┴±Æ↑∑└βæ┼©¢§0┌βα≤¿3«=",
- "description": "÷2α≠┌€↑αž€1≥¿Ÿæ≈¿¶↕0│→↕≈│2§┤│€α6¿¶↕0─€÷├┌3µ→─Æ5γ┌→↕≥¿┬↕┤│γ┼├¶α«├±β™↓¿Æœ├┌Ÿš≥¿3š┤│¶↕1┌2α≤¿→↕0─€÷├┌2™≠¿¶↕↓└Æ50±¢├├┐¢§α¿•↕∑│┬↕0─€÷├÷βæ┤±3µ«│2§┤│€α6±¢µ∑│24├±Æ5┼ž™šα±Æ§0×β™0─¢¿α×€9┴±Æ↑∑└β™0─Æ9≤ž€1≥¿Ÿæ≈¿¶←├┐¢§αž•┐≤┌€0├┌γæ≤ž€š1─Æ↑┼š→↕┬¿Æ¿≥┌β÷├┌Ÿæ┬│€α↓─€α≤¿←==",
- "author": "÷3µα¿β™≤│→↕€±Æ↑┼±¶↔8┌3µα¿β™≤│→5β±Æ↑┼±÷↕γ│Æ™∑│•5┴│20+ž•┤Δ┐Ÿµ←¥┬8≥┐3┐3©βš┤±βα↓│2¿0©β§≥│¶┼=",
- "version": "«•4→©┴œ=",
- "license": "×÷α÷",
- "repository": "≥↓Æ↑«®4→š™÷œβ│─×→┬←4¿│8→≈æ÷↔└œ≈≈∫©®γ┬├®2Æ∫├œ∫¥β→≈└└µØ©€2Æ20•«≈←┼ž√+↑§∫/€┐±÷««9─¶↔«±12•2¶¥§├↔Δ1«9"
- },
- {
- "name": "│Æ™→─2æ┼©¢šα±Æ§0",
- "description": "÷βæ≤¿€æ→ž‰1┤┌β≠┼│3┐≤ž€™↓ž™šα±Æ§0ž€§≥│¢↕≥│βæ≤┐Ÿ«=",
- "author": "┌2α┬─¢š┤─┬1↓",
- "version": "«¶4↑©┴ž=",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×¥γ‰│¶→0∑®↑→│¿├©¿ž5±©€┬├→≤/↑3æ├⁄7©βš©‰↓┐ƶ/§│‰←"
- },
- {
- "name": "│Æ™0¿¢š∑±Æ←≠─Ƨ≥│γ«=",
- "description": "×€™0¿¢§0ž€α┴│24├¿β9≤┐Ÿ«├±Æ5┼ž‰§×÷→↕β│3ž├┌2æ≈¿┬1Δ│3§0─Æ5γž€1┤┐€æ→─Æ™≈ž€µα┌2αγ│┬↕∑±29≤┌→4=",
- "author": "│γæ≈│↔==",
- "version": "«¶4↑«¶40",
- "license": "œ¢↕┤±2┤α©×ž≤«↔==",
- "repository": "≥↓Æ↑«®4→š™÷œβ│─×→┬←4¿│8→≈æ÷↔└œ≈≈∫©®γ┬├®2Æ2•↑Δ2¶↑ž≈2µš®┼→æ┼┼œ∫œ└¶↔¥┌┬¶®γ€1α┼•«α─×∫§┌œ§┴€÷Ø×0="
+ {
+ "name": "googlers-tools",
+ "description": "My own tools / scripts that i use.",
+ "author": "Der_Googler ",
+ "version": "1.2.8",
+ "license": "GPL-3.0",
+ "repository": "https://www.npmjs.com/package/googlers-tools"
+ },
+ {
+ "name": "highlight.js",
+ "description": "Syntax highlighting with language autodetection.",
+ "author": "Josh Goebel ",
+ "version": "11.6.0",
+ "license": "BSD-3-Clause",
+ "repository": "https://www.npmjs.com/package/highlight.js"
+ },
+ {
+ "name": "jss",
+ "description": "A lib for generating Style Sheets with JavaScript.",
+ "author": "JSS Team",
+ "version": "10.9.0",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/jss"
+ },
+ {
+ "name": "jss-preset-default",
+ "description": "Default preset for JSS with selected plugins.",
+ "author": "JSS Team",
+ "version": "10.9.0",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/jss-preset-default"
+ },
+ {
+ "name": "localized-strings",
+ "description": "Simple module to localize the strings of any JS based program using the same syntax used in the ReactLocalization and ReactNativeLocalization module, use 'npm run build' before publishing",
+ "author": "Stefano Falda (http://www.babisoft.com)",
+ "version": "0.2.4",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/localized-strings"
+ },
+ {
+ "name": "markdown-to-jsx",
+ "description": "Convert markdown to JSX with ease for React and React-like projects. Super lightweight and highly configurable.",
+ "author": "Evan Jacobs ",
+ "version": "7.1.7",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/markdown-to-jsx"
+ },
+ {
+ "name": "marked-react",
+ "description": "Render Markdown as React components",
+ "author": "sibiraj-s",
+ "version": "1.1.2",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/marked-react"
+ },
+ {
+ "name": "material-icons",
+ "description": "Latest icon fonts and CSS for self-hosting material design icons.",
+ "author": "null",
+ "version": "1.11.4",
+ "license": "Apache-2.0",
+ "repository": "https://www.npmjs.com/package/material-icons"
},
{
- "name": "│2š√¿Æ§0©Æ™↓┌2αγ│├==",
- "description": "µæ«→«⁄‰1ž€↕رβ∑α±3œ≤±¢§↓─Æ┐≤®•α├žŸ↕≥│γαβ─Æ↑≈",
- "author": "÷2α≤¿Ÿšαž™§≥┌β┤1┌←==",
- "version": "§•4↑©┴‰=",
- "license": "×÷α÷",
- "repository": "⁄⁄Æ↑¿«↕4¿§±««α√¶↔¢┴β┼6┼→¢α‰↔≈←≈0«•ž↑¶œ←↓→µ€/«┴œ9"
- },
+ "name": "object-assign",
+ "description": "ES2015 `Object.assign()` ponyfill",
+ "author": "Sindre Sorhus",
+ "version": "4.1.1",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/object-assign"
+ },
{
- "name": "│25↓¿Æ51─œ==",
- "description": "¶™µ§×⁄÷├ׯ9┬─Æ↑αž‰¿→±Æ1α┐29→─→↔βž™æšž‰§≥│¢↕≥│βæ≤┐Ÿ«=",
- "author": "│γæ≈│↔==",
- "version": "«┬4↑«┬4↑",
- "license": "œ¢↕┤±2┤α©×ž≤«↔==",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×↔5┬œ←→•€×βŸ™5α1↓ž1┼7/€§└─2÷↓09"
- },
+ "name": "onsenui",
+ "description": "HTML5 Mobile Framework & UI Components",
+ "author": "null",
+ "version": "2.12.1",
+ "license": "Apache-2.0",
+ "repository": "https://www.npmjs.com/package/onsenui"
+ },
{
- "name": "┌βæ┤±3œ=",
- "description": "÷βæ┤±3œ├─¢«├±¶↕®±¢¿┤÷2§→─¢↕0ž€↑∑±γš┤┌γ┼├¿β9→ž€š1─Æ↑┼─Æ5γžŸæ↓¿¢ž├─Æ50¿¢šβ±Æ§α┌→4=",
- "author": "│γæ≈│↔==",
- "version": "«×├≤«┬4←",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×®/š©‰→•1‰•«α≈∫√×µ┤≈│Ÿ€∑↓•∑1↓žµ«¿œ9Øœ=="
- },
+ "name": "react",
+ "description": "React is a JavaScript library for building user interfaces.",
+ "author": "null",
+ "version": "18.2.0",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/react"
+ },
{
- "name": "┌βæ┤±3œ≠¿€æ2─Æ§α©Æµα┐€æ┴┐↔==",
- "description": "µ€æ0¿Æ§0ž€µα┐βα┴¿¶↕0└¢↕αž€™≤¿•↕→¿Æ5┼¿¢ž├└Æ91┌┬↕┴│21←│25α│γœ├±Æ§┴│3š┼─Æ5γžŸµ≥ž€α0",
- "author": "ׯα┴─€™α│•↕«±Æ≠0─Æ9≤│3±=",
- "version": "«┬4→©┴ž=",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×®1æ├←→├β0•÷0┌8√×µ┤≈│Ÿ€∑↓•∑↑∫┬↑‰7Æ↑§©+2æ┴→/Δ∫┬↑≈׵ל=="
- },
+ "name": "react-device-detect",
+ "description": "Detect device type and render your component according to it",
+ "author": "Michael Laktionov",
+ "version": "2.2.2",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/react-device-detect"
+ },
{
- "name": "┌βæ┤±3œ≠¿€9≠",
- "description": "÷βæ┤±3œ├┌€™┴─2™γ¿¶↕β│3ž├┐29→─2α≤¿→↕3─¢µΔžŸµΔ¿¶↕‰×00≤",
- "author": "│γæ≈│↔==",
- "version": "«×├≤«┬4←",
- "license": "×÷α÷",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√×®/š©‰→•1‰•«α≈∫√×µ┤≈│Ÿ€∑↓•∑1↓žµ«¿œ9Øœ=="
- },
+ "name": "react-disappear",
+ "description": "Detects if the inner children are visible",
+ "author": "Der_Googler",
+ "version": "1.0.0",
+ "license": "null",
+ "repository": "https://www.npmjs.com/package/react-disappear"
+ },
{
- "name": "┌βæ┤±3œ≠│25↓¿Æ51─œ==",
- "description": "×25↓¿Æ4├æ÷┼├©¶↕¶¿Æ™┴┐•↕⁄│21←│25α│γµ↓ž€¿≥┌┬↕ž└Æš→─Æœ├œ29→¿€92±¶9œ─€9≤¿÷┐┤┌•↕↕┌Ÿ↕↓žŸ┐∑┐€├├ׯ™0¿¢š∑±Æ←├µ€æ↓─Æ┐≤ž€™≤¿•↕∑×1«├æ÷┼├±29≠┌€9≤¿Æ50┌←==",
- "author": "×25↓¿Æ4├æ÷┼├æ€æ┤│¶↔8┐€æ┤│÷↕≠│25┤±2‰≤─Æ8+",
- "version": "«¶4↑«┬4←",
- "license": "œ¢↕┤±2┤α©×ž≤«↔==",
- "repository": "≥↓Æ↑«®4→š™÷œβ│─×→┬←4¿│8→≈æ÷↔└œ≈≈∫©®γ┬├®2¥┘0•≈6√↑↕│Ÿβ±─┼←Æ4┼««←┤┼5↑←8¿©8→×↔="
- },
+ "name": "react-dom",
+ "description": "React package for working with the DOM.",
+ "author": "null",
+ "version": "18.2.0",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/react-dom"
+ },
{
- "name": "┌βæ┤±3œ≠│25↓¿Æ51─¢├=",
- "description": "×25↓¿Æ4├æ÷┼├©¶↕¶¿Æ™┴┐•↕⁄│21←│25α│γµ↓ž€¿≥┌┬↕ž└Æš→─Æœ├œ29→¿€92±¶9œ─€9≤¿÷┐┤┌•↕↕┌Ÿ↕↓žŸ┐∑┐€├├ׯ™0¿¢š∑±Æ←├µ€æ↓─Æ┐≤ž€™≤¿•↕∑×1«├æ÷┼├±29≠┌€9≤¿Æ50┌←==",
- "author": "µ€æ→¢0┐≥│2┐≈¿¢ž├Ø€∑∑│Æ15±β9α─€1↔¿€æ→¿29≥¿2↑α┌┬5┴│20+",
- "version": "«¶4←©┴÷=",
- "license": "│γæ≈│↔==",
- "repository": "↔¢┬1æœ14√↓─∑┼┴→↓↔®®1≤µ⁄€Δ€¶↑«α≠├√ו11┴‰8«ΔΔ•æ↓šž≥6§+┬├+→•→¶↑§Ÿæ├↔┴ž1┼7/€§æ±↔↑↑←9"
- },
+ "name": "react-onsenui",
+ "description": "Onsen UI - React Components for Hybrid Cordova/PhoneGap Apps with Material Design and iOS UI components",
+ "author": "Onsen UI Team ",
+ "version": "1.12.0",
+ "license": "Apache-2.0",
+ "repository": "https://www.npmjs.com/package/react-onsenui"
+ },
{
- "name": "┌βæ┤±3œ≠┌3α≤┐€™4©Æ┤∑¿2┤≈─Æ┐Δ┐€æ→",
- "description": "┌3α≤┐€™4ž€┤∑¿2┤≈─Æ┐Δ┐€α≤¿→↕┴│21←│25α│γœ├¿β9→žŸšα±Æ§0žŸ┐∑┐€├├┌Ÿš∑┌21√┌→↕≥┌┬↕Δ─Æ┐Δ│€αγ─Ÿµ√┌→↕┤┌3œ├┐¢§∑│β┌├─Æ5≈─Æ5αžŸ§0└Æ↑α┌←==",
- "author": "œ29≤│3ž├¶€™↓┐€α≤¿3«=",
- "version": "«×÷≤§¶4←",
- "license": "×÷α÷",
- "repository": "≥↓Æ↑«®4→š™÷œβ│─×→┬←4¿│8→≈æ÷↔└œ≈≈∫©®γ┬├®2Æ∑®/50┌0«•ž↑≤↕×€§×•↑↑↓5├ž®+↑2••≈≈↑€/æ→œ←≥6§+┬├+→•→¶↑§Ÿæ├⁄⁄─↑┬ו≈ž┴¶∑60±µ≥1┌┼│œ⁄€‰7┼œ∫œ└¶∫§┌œ§┴€÷Ø×0="
+ "name": "react-syntax-highlighter",
+ "description": "syntax highlighting component for react with prismjs or highlightjs ast using inline styles",
+ "author": "Conor Hastings",
+ "version": "15.5.0",
+ "license": "MIT",
+ "repository": "https://www.npmjs.com/package/react-syntax-highlighter"
}
]
diff --git a/Website/src/utils/native-licenses.json b/Website/src/utils/native-licenses.json
new file mode 100644
index 000000000..b9711cec2
--- /dev/null
+++ b/Website/src/utils/native-licenses.json
@@ -0,0 +1,34 @@
+[
+ {
+ "name": "androidx.browser:browser",
+ "description": "androidx.browser:browser:1.4.0",
+ "version": "1.4.0",
+ "license": "null",
+ "author": "null",
+ "repository": "https://mvnrepository.com/artifact/androidx.browser/browser/1.4.0"
+ },
+ {
+ "name": "com.github.topjohnwu.libsu:core",
+ "description": "com.github.topjohnwu.libsu:core:5.0.2",
+ "version": "5.0.2",
+ "license": "null",
+ "author": "null",
+ "repository": "https://mvnrepository.com/artifact/com.github.topjohnwu.libsu/core/5.0.2"
+ },
+ {
+ "name": "com.github.topjohnwu.libsu:io",
+ "description": "com.github.topjohnwu.libsu:io:5.0.1",
+ "version": "5.0.1",
+ "license": "null",
+ "author": "null",
+ "repository": "https://mvnrepository.com/artifact/com.github.topjohnwu.libsu/io/5.0.1"
+ },
+ {
+ "name": "androidx.appcompat:appcompat",
+ "description": "androidx.appcompat:appcompat:1.4.2",
+ "version": "1.4.2",
+ "license": "null",
+ "author": "null",
+ "repository": "https://mvnrepository.com/artifact/androidx.appcompat/appcompat/1.4.2"
+ }
+]
\ No newline at end of file
diff --git a/Website/tsconfig.json b/Website/tsconfig.json
index 22fde7f7a..3c96f5c5d 100644
--- a/Website/tsconfig.json
+++ b/Website/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"outDir": "./../Android/app/src/main/assets",
- "typeRoots": ["src/typings/global.d.ts"],
+ "typeRoots": ["node_modules/@types"],
"sourceMap": false,
"experimentalDecorators": true,
"declaration": false,
diff --git a/Website/webpack.config.ts b/Website/webpack.config.ts
index b710b822b..c9ae1a096 100644
--- a/Website/webpack.config.ts
+++ b/Website/webpack.config.ts
@@ -2,14 +2,7 @@ import { Configuration } from "webpack";
import { resolve, join } from "path";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
-
-const defConfig = {
- output: {
- filename: "bundle/[name].bundle.js",
- path: resolve(__dirname, "./../Android/app/src/main/assets"),
- assetModuleFilename: "files/[name].[ext]",
- },
-};
+import { defConfig } from "./webpack/defConfig";
const config: Configuration = {
entry: {
@@ -68,11 +61,7 @@ const config: Configuration = {
maxEntrypointSize: 512000,
maxAssetSize: 512000,
},
- plugins: [
- new MiniCssExtractPlugin({
- filename: "bundle/[name].bundle.css",
- }),
- ],
+ plugins: [],
resolve: {
fallback: {
path: false,
@@ -99,4 +88,4 @@ const config: Configuration = {
},
};
-export { defConfig, config };
+export default config;
diff --git a/Website/webpack.dev.ts b/Website/webpack.dev.ts
index 88fa42894..cdf742995 100644
--- a/Website/webpack.dev.ts
+++ b/Website/webpack.dev.ts
@@ -1,8 +1,11 @@
import { merge } from "webpack-merge";
-import { defConfig, config } from "./webpack.config";
+import { defConfig, Mode } from "./webpack/defConfig";
+import { devPlugins } from "./webpack/plugins";
+import config from "./webpack.config";
export default merge(config, {
- mode: "development",
+ mode: Mode.Development,
...defConfig,
+ ...devPlugins,
devtool: "source-map",
});
diff --git a/Website/webpack.prod.ts b/Website/webpack.prod.ts
index 1d50ff49b..06f04de07 100644
--- a/Website/webpack.prod.ts
+++ b/Website/webpack.prod.ts
@@ -1,10 +1,12 @@
import { merge } from "webpack-merge";
-import { defConfig, config } from "./webpack.config";
-import UglifyJsPlugin from "uglifyjs-webpack-plugin";
+import { defConfig, Mode } from "./webpack/defConfig";
+import config from "./webpack.config";
+import { ProdPlugins } from "./webpack/plugins";
export default merge(config, {
- mode: "production",
+ mode: Mode.Production,
...defConfig,
+ ...ProdPlugins,
optimization: {
//@ts-ignore
minimizer: [new UglifyJsPlugin()],
diff --git a/Website/webpack/defConfig.ts b/Website/webpack/defConfig.ts
new file mode 100644
index 000000000..ba28bafe2
--- /dev/null
+++ b/Website/webpack/defConfig.ts
@@ -0,0 +1,25 @@
+import { resolve } from "path";
+import { Configuration } from "webpack";
+
+export enum Config {
+ Blue,
+ AndroidOutputPath = "./../../Android/app/src/main/assets",
+ OutputFilename = "bundle/[name].bundle.js",
+ AssetModuleFilename = "files/[name].[ext]",
+ CssOutputFilename = "bundle/[name].bundle.css",
+}
+
+export enum Mode {
+ Production = "production",
+ Development = "development",
+}
+
+const defConfig: Configuration = {
+ output: {
+ filename: Config.OutputFilename as string,
+ path: resolve(__dirname, Config.AndroidOutputPath),
+ assetModuleFilename: Config.AssetModuleFilename as string,
+ },
+};
+
+export { defConfig };
diff --git a/Website/webpack/plugins.ts b/Website/webpack/plugins.ts
new file mode 100644
index 000000000..c4209e6f8
--- /dev/null
+++ b/Website/webpack/plugins.ts
@@ -0,0 +1,23 @@
+import MiniCssExtractPlugin from "mini-css-extract-plugin";
+import UglifyJsPlugin from "uglifyjs-webpack-plugin";
+import { Configuration } from "webpack";
+import { Config } from "./defConfig";
+
+const ProdPlugins: Configuration = {
+ plugins: [
+ // @ts-ignore
+ new UglifyJsPlugin(),
+ new MiniCssExtractPlugin({
+ filename: Config.CssOutputFilename as string,
+ }),
+ ],
+};
+const devPlugins: Configuration = {
+ plugins: [
+ new MiniCssExtractPlugin({
+ filename: Config.CssOutputFilename as string,
+ }),
+ ],
+};
+
+export { devPlugins, ProdPlugins };
diff --git a/update.py b/update.py
index 748993ebd..f9e4c497a 100644
--- a/update.py
+++ b/update.py
@@ -2,8 +2,8 @@
# Run "python3 update.py"
-new_version = "1.4.1"
-new_versionCode = 141
+new_version = "1.4.2"
+new_versionCode = 142
Website_version = "./Website/package.json"
Android_version = "./Android/app/build.gradle"