mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 16:33:26 +00:00
feat: update sheet modal
This commit is contained in:
@@ -61,6 +61,7 @@
|
|||||||
"react-native-context-menu-view": "^1.14.1",
|
"react-native-context-menu-view": "^1.14.1",
|
||||||
"react-native-gesture-handler": "~2.14.1",
|
"react-native-gesture-handler": "~2.14.1",
|
||||||
"react-native-ios-modal": "^0.1.8",
|
"react-native-ios-modal": "^0.1.8",
|
||||||
|
"react-native-markdown-display": "^7.0.2",
|
||||||
"react-native-mmkv": "^2.12.2",
|
"react-native-mmkv": "^2.12.2",
|
||||||
"react-native-modal": "^13.0.1",
|
"react-native-modal": "^13.0.1",
|
||||||
"react-native-quick-base64": "^2.0.8",
|
"react-native-quick-base64": "^2.0.8",
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import type { SelectProps } from "tamagui";
|
import type { SelectProps } from "tamagui";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { Platform } from "react-native";
|
import { Platform } from "react-native";
|
||||||
|
import Markdown from "react-native-markdown-display";
|
||||||
import * as Application from "expo-application";
|
import * as Application from "expo-application";
|
||||||
import * as Brightness from "expo-brightness";
|
import * as Brightness from "expo-brightness";
|
||||||
import * as WebBrowser from "expo-web-browser";
|
import * as WebBrowser from "expo-web-browser";
|
||||||
@@ -13,6 +14,7 @@ import { useToastController } from "@tamagui/toast";
|
|||||||
import {
|
import {
|
||||||
Adapt,
|
Adapt,
|
||||||
Label,
|
Label,
|
||||||
|
ScrollView,
|
||||||
Select,
|
Select,
|
||||||
Separator,
|
Separator,
|
||||||
Sheet,
|
Sheet,
|
||||||
@@ -44,6 +46,9 @@ export default function SettingsScreen() {
|
|||||||
const { gestureControls, setGestureControls, autoPlay, setAutoPlay } =
|
const { gestureControls, setGestureControls, autoPlay, setAutoPlay } =
|
||||||
usePlayerSettingsStore();
|
usePlayerSettingsStore();
|
||||||
const toastController = useToastController();
|
const toastController = useToastController();
|
||||||
|
const [showUpdateSheet, setShowUpdateSheet] = useState(false);
|
||||||
|
const [updateMarkdownContent, setUpdateMarkdownContent] = useState("");
|
||||||
|
const [downloadUrl, setDownloadUrl] = useState("");
|
||||||
|
|
||||||
const handleGestureControlsToggle = async (isEnabled: boolean) => {
|
const handleGestureControlsToggle = async (isEnabled: boolean) => {
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
@@ -57,14 +62,17 @@ export default function SettingsScreen() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleVersionPress = async () => {
|
const handleVersionPress = async () => {
|
||||||
const url = await checkForUpdate();
|
const res = await checkForUpdate();
|
||||||
if (url) {
|
if (res) {
|
||||||
toastController.show("Update available", {
|
setUpdateMarkdownContent(res.data.body!);
|
||||||
burntOptions: { preset: "none" },
|
setDownloadUrl(
|
||||||
native: true,
|
res.data.assets.find(
|
||||||
duration: 500,
|
(asset) =>
|
||||||
});
|
asset.name ===
|
||||||
await WebBrowser.openBrowserAsync(url);
|
`movie-web.${Platform.select({ ios: "ipa", android: "apk" })}`,
|
||||||
|
)?.browser_download_url ?? "",
|
||||||
|
);
|
||||||
|
setShowUpdateSheet(true);
|
||||||
} else {
|
} else {
|
||||||
toastController.show("No updates available", {
|
toastController.show("No updates available", {
|
||||||
burntOptions: { preset: "none" },
|
burntOptions: { preset: "none" },
|
||||||
@@ -122,10 +130,87 @@ export default function SettingsScreen() {
|
|||||||
</XStack>
|
</XStack>
|
||||||
</YStack>
|
</YStack>
|
||||||
</View>
|
</View>
|
||||||
|
<UpdateSheet
|
||||||
|
markdownContent={updateMarkdownContent}
|
||||||
|
open={showUpdateSheet}
|
||||||
|
setShowUpdateSheet={setShowUpdateSheet}
|
||||||
|
downloadUrl={downloadUrl}
|
||||||
|
/>
|
||||||
</ScreenLayout>
|
</ScreenLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function UpdateSheet({
|
||||||
|
markdownContent,
|
||||||
|
open,
|
||||||
|
setShowUpdateSheet,
|
||||||
|
downloadUrl,
|
||||||
|
}: {
|
||||||
|
markdownContent: string;
|
||||||
|
open: boolean;
|
||||||
|
setShowUpdateSheet: (value: boolean) => void;
|
||||||
|
downloadUrl: string;
|
||||||
|
}) {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Sheet
|
||||||
|
modal
|
||||||
|
open={open}
|
||||||
|
onOpenChange={setShowUpdateSheet}
|
||||||
|
dismissOnSnapToBottom
|
||||||
|
dismissOnOverlayPress
|
||||||
|
animationConfig={{
|
||||||
|
type: "spring",
|
||||||
|
damping: 20,
|
||||||
|
mass: 1.2,
|
||||||
|
stiffness: 250,
|
||||||
|
}}
|
||||||
|
snapPoints={[35]}
|
||||||
|
>
|
||||||
|
<Sheet.Handle backgroundColor="$sheetHandle" />
|
||||||
|
<Sheet.Frame
|
||||||
|
backgroundColor="$sheetBackground"
|
||||||
|
padding="$4"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
>
|
||||||
|
<ScrollView>
|
||||||
|
<Markdown
|
||||||
|
style={{
|
||||||
|
text: {
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{markdownContent}
|
||||||
|
</Markdown>
|
||||||
|
</ScrollView>
|
||||||
|
<MWButton
|
||||||
|
type="secondary"
|
||||||
|
backgroundColor="$sheetItemBackground"
|
||||||
|
icon={
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={Platform.select({ ios: "apple", android: "android" })}
|
||||||
|
size={24}
|
||||||
|
color={theme.buttonSecondaryText.val}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onPress={() => WebBrowser.openBrowserAsync(downloadUrl)}
|
||||||
|
>
|
||||||
|
Download
|
||||||
|
</MWButton>
|
||||||
|
</Sheet.Frame>
|
||||||
|
<Sheet.Overlay
|
||||||
|
animation="lazy"
|
||||||
|
backgroundColor="rgba(0, 0, 0, 0.8)"
|
||||||
|
enterStyle={{ opacity: 0 }}
|
||||||
|
exitStyle={{ opacity: 0 }}
|
||||||
|
/>
|
||||||
|
</Sheet>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function ThemeSelector(props: SelectProps) {
|
export function ThemeSelector(props: SelectProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const themeStore = useThemeStore((s) => s.theme);
|
const themeStore = useThemeStore((s) => s.theme);
|
||||||
|
@@ -24,7 +24,7 @@ function isVersionHigher(newVersion: string, currentVersion: string): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkForUpdate(): Promise<string | undefined> {
|
export async function checkForUpdate() {
|
||||||
const octokit = new Octokit();
|
const octokit = new Octokit();
|
||||||
|
|
||||||
const res = await octokit.repos
|
const res = await octokit.repos
|
||||||
@@ -40,6 +40,6 @@ export async function checkForUpdate(): Promise<string | undefined> {
|
|||||||
const currentVersion = Application.nativeApplicationVersion ?? "0.0.0";
|
const currentVersion = Application.nativeApplicationVersion ?? "0.0.0";
|
||||||
|
|
||||||
if (isVersionHigher(latestVersion, currentVersion)) {
|
if (isVersionHigher(latestVersion, currentVersion)) {
|
||||||
return res.data.html_url;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
69
pnpm-lock.yaml
generated
69
pnpm-lock.yaml
generated
@@ -155,6 +155,9 @@ importers:
|
|||||||
react-native-ios-modal:
|
react-native-ios-modal:
|
||||||
specifier: ^0.1.8
|
specifier: ^0.1.8
|
||||||
version: 0.1.8(react-native@0.73.6)(react@18.2.0)
|
version: 0.1.8(react-native@0.73.6)(react@18.2.0)
|
||||||
|
react-native-markdown-display:
|
||||||
|
specifier: ^7.0.2
|
||||||
|
version: 7.0.2(react-native@0.73.6)(react@18.2.0)
|
||||||
react-native-mmkv:
|
react-native-mmkv:
|
||||||
specifier: ^2.12.2
|
specifier: ^2.12.2
|
||||||
version: 2.12.2(react-native@0.73.6)(react@18.2.0)
|
version: 2.12.2(react-native@0.73.6)(react@18.2.0)
|
||||||
@@ -6262,6 +6265,10 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/camelize@1.0.1:
|
||||||
|
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/caniuse-lite@1.0.30001583:
|
/caniuse-lite@1.0.30001583:
|
||||||
resolution: {integrity: sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==}
|
resolution: {integrity: sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==}
|
||||||
|
|
||||||
@@ -6786,6 +6793,11 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/css-color-keywords@1.0.0:
|
||||||
|
resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/css-in-js-utils@3.1.0:
|
/css-in-js-utils@3.1.0:
|
||||||
resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==}
|
resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -6802,6 +6814,14 @@ packages:
|
|||||||
nth-check: 2.1.1
|
nth-check: 2.1.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/css-to-react-native@3.2.0:
|
||||||
|
resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
|
||||||
|
dependencies:
|
||||||
|
camelize: 1.0.1
|
||||||
|
css-color-keywords: 1.0.0
|
||||||
|
postcss-value-parser: 4.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/css-tree@1.1.3:
|
/css-tree@1.1.3:
|
||||||
resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
|
resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
@@ -7162,6 +7182,10 @@ packages:
|
|||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/entities@2.0.3:
|
||||||
|
resolution: {integrity: sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/entities@4.5.0:
|
/entities@4.5.0:
|
||||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
@@ -9809,6 +9833,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/linkify-it@2.2.0:
|
||||||
|
resolution: {integrity: sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==}
|
||||||
|
dependencies:
|
||||||
|
uc.micro: 1.0.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
/locate-path@3.0.0:
|
/locate-path@3.0.0:
|
||||||
resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
|
resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -9947,6 +9977,17 @@ packages:
|
|||||||
tmpl: 1.0.5
|
tmpl: 1.0.5
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/markdown-it@10.0.0:
|
||||||
|
resolution: {integrity: sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
argparse: 1.0.10
|
||||||
|
entities: 2.0.3
|
||||||
|
linkify-it: 2.2.0
|
||||||
|
mdurl: 1.0.1
|
||||||
|
uc.micro: 1.0.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
/marky@1.2.5:
|
/marky@1.2.5:
|
||||||
resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==}
|
resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -9991,6 +10032,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
|
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/mdurl@1.0.1:
|
||||||
|
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/memoize-one@5.2.1:
|
/memoize-one@5.2.1:
|
||||||
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -11497,6 +11542,12 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-native-fit-image@1.5.5:
|
||||||
|
resolution: {integrity: sha512-Wl3Vq2DQzxgsWKuW4USfck9zS7YzhvLNPpkwUUCF90bL32e1a0zOVQ3WsJILJOwzmPdHfzZmWasiiAUNBkhNkg==}
|
||||||
|
dependencies:
|
||||||
|
prop-types: 15.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-native-gesture-handler@2.14.1(react-native@0.73.6)(react@18.2.0):
|
/react-native-gesture-handler@2.14.1(react-native@0.73.6)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-YiM1BApV4aKeuwsM6O4C2ufwewYEKk6VMXOt0YqEZFMwABBFWhXLySFZYjBSNRU2USGppJbfHP1q1DfFQpKhdA==}
|
resolution: {integrity: sha512-YiM1BApV4aKeuwsM6O4C2ufwewYEKk6VMXOt0YqEZFMwABBFWhXLySFZYjBSNRU2USGppJbfHP1q1DfFQpKhdA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -11522,6 +11573,20 @@ packages:
|
|||||||
react-native: 0.73.6(@babel/core@7.23.9)(@babel/preset-env@7.23.9)(react@18.2.0)
|
react-native: 0.73.6(@babel/core@7.23.9)(@babel/preset-env@7.23.9)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-native-markdown-display@7.0.2(react-native@0.73.6)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-Mn4wotMvMfLAwbX/huMLt202W5DsdpMO/kblk+6eUs55S57VVNni1gzZCh5qpznYLjIQELNh50VIozEfY6fvaQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.2.0'
|
||||||
|
react-native: '>=0.50.4'
|
||||||
|
dependencies:
|
||||||
|
css-to-react-native: 3.2.0
|
||||||
|
markdown-it: 10.0.0
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 18.2.0
|
||||||
|
react-native: 0.73.6(@babel/core@7.23.9)(@babel/preset-env@7.23.9)(react@18.2.0)
|
||||||
|
react-native-fit-image: 1.5.5
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-native-mmkv@2.12.2(react-native@0.73.6)(react@18.2.0):
|
/react-native-mmkv@2.12.2(react-native@0.73.6)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-6058Aq0p57chPrUutLGe9fYoiDVDNMU2PKV+lLFUJ3GhoHvUrLdsS1PDSCLr00yqzL4WJQ7TTzH+V8cpyrNcfg==}
|
resolution: {integrity: sha512-6058Aq0p57chPrUutLGe9fYoiDVDNMU2PKV+lLFUJ3GhoHvUrLdsS1PDSCLr00yqzL4WJQ7TTzH+V8cpyrNcfg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -13243,6 +13308,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==}
|
resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/uc.micro@1.0.6:
|
||||||
|
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/uglify-js@3.17.4:
|
/uglify-js@3.17.4:
|
||||||
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
|
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
|
||||||
engines: {node: '>=0.8.0'}
|
engines: {node: '>=0.8.0'}
|
||||||
|
Reference in New Issue
Block a user