mirror of
https://github.com/standardnotes/mobile.git
synced 2026-02-05 21:41:23 -05:00
feature: WIP themes
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
"react-native-webview": "^10.7.0",
|
||||
"react-navigation-header-buttons": "^5.0.2",
|
||||
"sn-textview": "standardnotes/sn-textview#f42f0bf",
|
||||
"snjs": "standardnotes/snjs#84b0403",
|
||||
"snjs": "standardnotes/snjs#27688ba",
|
||||
"standard-notes-rn": "standardnotes/standard-notes-rn",
|
||||
"styled-components": "^5.1.1"
|
||||
},
|
||||
|
||||
39
src/App.tsx
39
src/App.tsx
@@ -29,6 +29,7 @@ import { MainSideMenu } from '@Screens/SideMenu/MainSideMenu';
|
||||
import { NoteSideMenu } from '@Screens/SideMenu/NoteSideMenu';
|
||||
import { ICON_CHECKMARK, ICON_CLOSE, ICON_MENU } from '@Style/icons';
|
||||
import { StyleKit, StyleKitContext } from '@Style/StyleKit';
|
||||
import { StyleKitTheme } from '@Style/Themes/styled-components';
|
||||
import { getDefaultDrawerWidth } from '@Style/Util/getDefaultDraerWidth';
|
||||
import React, {
|
||||
useCallback,
|
||||
@@ -420,35 +421,55 @@ const AppComponent: React.FC<{
|
||||
env: 'prod' | 'dev';
|
||||
}> = ({ application, env }) => {
|
||||
const [ready, setReady] = useState(false);
|
||||
const styleKit = useRef<StyleKit | undefined>(undefined);
|
||||
const styleKit = useRef<StyleKit>();
|
||||
const [activeTheme, setActiveTheme] = useState<StyleKitTheme | undefined>();
|
||||
|
||||
const setStyleKitRef = useCallback((node: StyleKit | undefined) => {
|
||||
if (node) {
|
||||
node.addThemeChangeObserver(() => {
|
||||
setActiveTheme(node.theme);
|
||||
});
|
||||
}
|
||||
|
||||
// Save a reference to the node
|
||||
styleKit.current = node;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let styleKitInstance: StyleKit;
|
||||
const loadApplication = async () => {
|
||||
await application?.prepareForLaunch({
|
||||
receiveChallenge: async challenge => {
|
||||
application!.promptForChallenge(challenge);
|
||||
},
|
||||
});
|
||||
styleKit.current = new StyleKit(application);
|
||||
await styleKit.current.init();
|
||||
styleKitInstance = new StyleKit(application);
|
||||
await styleKitInstance.init();
|
||||
setStyleKitRef(styleKitInstance);
|
||||
setActiveTheme(styleKitInstance.theme);
|
||||
setReady(true);
|
||||
};
|
||||
setReady(false);
|
||||
loadApplication();
|
||||
}, [application, env]);
|
||||
|
||||
if (!ready || !styleKit.current) {
|
||||
return () => {
|
||||
styleKitInstance?.deinit();
|
||||
setStyleKitRef(undefined);
|
||||
};
|
||||
}, [application, env, setStyleKitRef]);
|
||||
|
||||
if (!ready || !styleKit.current || !activeTheme) {
|
||||
return null;
|
||||
}
|
||||
// TODO: better modes support
|
||||
|
||||
return (
|
||||
<NavigationContainer
|
||||
theme={{
|
||||
...DefaultTheme,
|
||||
colors: {
|
||||
...DefaultTheme.colors,
|
||||
background: styleKit.current.theme!.stylekitBackgroundColor,
|
||||
border: styleKit.current.theme!.stylekitBorderColor,
|
||||
background: activeTheme.stylekitBackgroundColor,
|
||||
border: activeTheme.stylekitBorderColor,
|
||||
},
|
||||
}}
|
||||
onReady={() => {
|
||||
@@ -459,7 +480,7 @@ const AppComponent: React.FC<{
|
||||
<StatusBar translucent />
|
||||
{styleKit.current && (
|
||||
<>
|
||||
<ThemeProvider theme={styleKit.current.theme!}>
|
||||
<ThemeProvider theme={activeTheme}>
|
||||
<ActionSheetProvider>
|
||||
<StyleKitContext.Provider value={styleKit.current}>
|
||||
<MainStackComponent env={env} />
|
||||
|
||||
@@ -65,6 +65,7 @@ export const CompanySection = (props: Props) => {
|
||||
<SectionHeader title={props.title} />
|
||||
|
||||
<ButtonCell
|
||||
first
|
||||
leftAligned={true}
|
||||
title="Help"
|
||||
onPress={() => openUrl('help')}
|
||||
|
||||
@@ -3,9 +3,11 @@ import { useNavigation } from '@react-navigation/native';
|
||||
import { ApplicationContext } from '@Root/ApplicationContext';
|
||||
import { SCREEN_SETTINGS } from '@Screens/screens';
|
||||
import { ICON_SETTINGS } from '@Style/icons';
|
||||
import { StyleKit } from '@Style/StyleKit';
|
||||
import { StyleKit, StyleKitContext, ThemeContent } from '@Style/StyleKit';
|
||||
import _ from 'lodash';
|
||||
import React, {
|
||||
Fragment,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
@@ -15,7 +17,7 @@ import { Platform } from 'react-native';
|
||||
import FAB from 'react-native-fab';
|
||||
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
|
||||
import Icon from 'react-native-vector-icons/Ionicons';
|
||||
import { ContentType, SNTag, SNTheme } from 'snjs';
|
||||
import { ContentType, SNTag, SNTheme, ThemeMutator } from 'snjs';
|
||||
import { ThemeContext } from 'styled-components/native';
|
||||
import {
|
||||
FirstSafeAreaView,
|
||||
@@ -33,6 +35,7 @@ type Props = {
|
||||
export const MainSideMenu = ({ drawerRef }: Props): JSX.Element => {
|
||||
// Context
|
||||
const theme = useContext(ThemeContext);
|
||||
const styleKit = useContext(StyleKitContext);
|
||||
const application = useContext(ApplicationContext);
|
||||
const navigation = useNavigation();
|
||||
|
||||
@@ -54,7 +57,41 @@ export const MainSideMenu = ({ drawerRef }: Props): JSX.Element => {
|
||||
return removeTagChangeObserver;
|
||||
});
|
||||
|
||||
const onThemeSelect = (_theme: SNTheme) => {};
|
||||
const onSystemThemeSelect = useCallback(
|
||||
async (selectedTheme: ThemeContent) => {
|
||||
const oldTheme = application!.findItem(styleKit!.activeThemeId!) as
|
||||
| SNTheme
|
||||
| undefined;
|
||||
|
||||
styleKit?.activateSystemTheme(selectedTheme.uuid);
|
||||
if (oldTheme?.isTheme() && oldTheme.isMobileActive()) {
|
||||
await application?.changeAndSaveItem(oldTheme.uuid, mutator => {
|
||||
const themeMutator = mutator as ThemeMutator;
|
||||
themeMutator.setMobileActive(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
[application, styleKit]
|
||||
);
|
||||
|
||||
const onThemeSelect = useCallback(
|
||||
async (selectedTheme: SNTheme) => {
|
||||
if (!selectedTheme.isMobileActive()) {
|
||||
await application?.changeItem(selectedTheme.uuid, mutator => {
|
||||
const themeMutator = mutator as ThemeMutator;
|
||||
themeMutator.setMobileActive(true);
|
||||
});
|
||||
if (application!.findItem(styleKit!.activeThemeId!)) {
|
||||
await application?.changeItem(styleKit!.activeThemeId!, mutator => {
|
||||
const themeMutator = mutator as ThemeMutator;
|
||||
themeMutator.setMobileActive(false);
|
||||
});
|
||||
}
|
||||
await application?.sync();
|
||||
}
|
||||
},
|
||||
[application, styleKit]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribeStreamThemes = application?.streamItems(
|
||||
@@ -68,18 +105,65 @@ export const MainSideMenu = ({ drawerRef }: Props): JSX.Element => {
|
||||
return unsubscribeStreamThemes;
|
||||
}, [application]);
|
||||
|
||||
const iconDescriptorForTheme = (currentTheme: SNTheme | ThemeContent) => {
|
||||
const desc = {
|
||||
type: 'circle',
|
||||
side: 'right' as 'right',
|
||||
};
|
||||
|
||||
const dockIcon =
|
||||
currentTheme.package_info && currentTheme.package_info.dock_icon;
|
||||
|
||||
if (dockIcon && dockIcon.type === 'circle') {
|
||||
_.merge(desc, {
|
||||
backgroundColor: dockIcon.background_color,
|
||||
borderColor: dockIcon.border_color,
|
||||
});
|
||||
} else {
|
||||
_.merge(desc, {
|
||||
backgroundColor: theme.stylekitInfoColor,
|
||||
borderColor: theme.stylekitInfoColor,
|
||||
});
|
||||
}
|
||||
|
||||
return desc;
|
||||
};
|
||||
|
||||
const themeOptions = useMemo(() => {
|
||||
let options: SideMenuOption[] = themes
|
||||
.filter(el => !el.errorDecrypting)
|
||||
.map(mapTheme => ({
|
||||
text: mapTheme.name,
|
||||
key: mapTheme.uuid,
|
||||
dimmed: mapTheme.getNotAvailOnMobile(),
|
||||
onSelect: () => onThemeSelect(mapTheme),
|
||||
}));
|
||||
const options: SideMenuOption[] = styleKit!
|
||||
.systemThemes()
|
||||
.map(systemTheme => ({
|
||||
text: systemTheme?.name,
|
||||
key: systemTheme?.uuid,
|
||||
iconDesc: iconDescriptorForTheme(systemTheme),
|
||||
dimmed: false,
|
||||
onSelect: () => onSystemThemeSelect(systemTheme),
|
||||
selected: styleKit!.activeThemeId === systemTheme?.uuid,
|
||||
}))
|
||||
.concat(
|
||||
themes
|
||||
.filter(el => !el.errorDecrypting)
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map(mapTheme => ({
|
||||
text: mapTheme.name,
|
||||
key: mapTheme.uuid,
|
||||
iconDesc: iconDescriptorForTheme(mapTheme),
|
||||
dimmed: mapTheme.getNotAvailOnMobile(),
|
||||
onSelect: () => onThemeSelect(mapTheme),
|
||||
selected: styleKit!.activeThemeId === mapTheme.uuid,
|
||||
}))
|
||||
);
|
||||
|
||||
return options;
|
||||
}, [themes]);
|
||||
// We want to also track activeThemeId
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [
|
||||
styleKit,
|
||||
styleKit?.activeThemeId,
|
||||
themes,
|
||||
onSystemThemeSelect,
|
||||
onThemeSelect,
|
||||
]);
|
||||
|
||||
const onTagSelect = async (tag: SNTag) => {
|
||||
if (tag.conflictOf) {
|
||||
|
||||
@@ -34,20 +34,7 @@ export const TagSelectionList = (props: Props): JSX.Element => {
|
||||
if (props.contentType === ContentType.SmartTag) {
|
||||
setTags(application!.getSmartTags());
|
||||
} else {
|
||||
setTags(
|
||||
(application!.getItems(props.contentType) as SNTag[]).sort((a, b) => {
|
||||
if (!a.title) {
|
||||
return -1;
|
||||
}
|
||||
if (!b.title) {
|
||||
return 1;
|
||||
}
|
||||
if (!a.title && !b.title) {
|
||||
return 0;
|
||||
}
|
||||
return a.title.localeCompare(b.title);
|
||||
})
|
||||
);
|
||||
setTags(application!.getDisplayableItems(props.contentType) as SNTag[]);
|
||||
}
|
||||
}, [application, props.contentType]);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MobileApplication } from '@Lib/application';
|
||||
import ThemeDownloader from '@Style/Util/ThemeDownloader';
|
||||
import CSSParser from '@Style/Util/CSSParser';
|
||||
import {
|
||||
DARK_CONTENT,
|
||||
keyboardColorForTheme,
|
||||
@@ -17,8 +17,9 @@ import {
|
||||
TextStyle,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import { ComponentArea, removeFromArray, SNComponent, SNTheme } from 'snjs';
|
||||
import { ContentType, removeFromArray, SNComponent, SNTheme } from 'snjs';
|
||||
import { UuidString } from 'snjs/dist/@types/types';
|
||||
import THEME_DARK_JSON from './Themes/blue-dark.json';
|
||||
import THEME_BLUE_JSON from './Themes/blue.json';
|
||||
import THEME_RED_JSON from './Themes/red.json';
|
||||
import { StyleKitTheme } from './Themes/styled-components';
|
||||
@@ -31,12 +32,14 @@ export interface ThemeContent {
|
||||
name: string;
|
||||
luminosity?: number;
|
||||
isSwapIn?: boolean;
|
||||
uuid: string;
|
||||
variables: StyleKitTheme;
|
||||
package_info: SNComponent['package_info'];
|
||||
}
|
||||
|
||||
enum SystemThemes {
|
||||
Blue = 'Blue',
|
||||
Dark = 'Dark',
|
||||
Red = 'Red',
|
||||
}
|
||||
|
||||
@@ -46,8 +49,8 @@ export const StyleKitContext = React.createContext<StyleKit | undefined>(
|
||||
|
||||
export class StyleKit {
|
||||
observers: ThemeChangeObserver[] = [];
|
||||
private themeData: Partial<Record<UuidString, ThemeContent>> = {};
|
||||
activeTheme?: string;
|
||||
private themeData: Record<UuidString, ThemeContent> = {};
|
||||
activeThemeId?: string;
|
||||
currentDarkMode: ColorSchemeName;
|
||||
static constants = {
|
||||
mainTextFontSize: 16,
|
||||
@@ -74,28 +77,17 @@ export class StyleKit {
|
||||
this.unregisterComponentHandler && this.unregisterComponentHandler();
|
||||
}
|
||||
|
||||
// onAppEvent(event: ApplicationEvent) {
|
||||
// super.onAppEvent(event);
|
||||
// if (event === ApplicationEvent.SignedOut) {
|
||||
// this.resetToSystemTheme();
|
||||
// }
|
||||
// }
|
||||
|
||||
private registerObservers() {
|
||||
this.unregisterComponentHandler = this.application!.componentManager!.registerHandler(
|
||||
{
|
||||
identifier: 'themeManager',
|
||||
areas: [ComponentArea.Themes],
|
||||
activationHandler: (uuid, component) => {
|
||||
if (component?.active) {
|
||||
console.log('activeTheme');
|
||||
// this.activateTheme(component as SNTheme);
|
||||
} else {
|
||||
// this.deactivateTheme(uuid);
|
||||
}
|
||||
},
|
||||
this.application.streamItems(ContentType.Theme, items => {
|
||||
const themes = items as SNTheme[];
|
||||
const activeTheme = themes.find(el => {
|
||||
return !el.deleted && el.isMobileActive();
|
||||
});
|
||||
|
||||
if (activeTheme && activeTheme.uuid !== this.activeThemeId) {
|
||||
this.activateExternalTheme(activeTheme);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private findOrCreateDataForTheme(themeId: string) {
|
||||
@@ -110,11 +102,19 @@ export class StyleKit {
|
||||
private buildSystemThemesAndData() {
|
||||
const themeData = [
|
||||
{
|
||||
uuid: SystemThemes.Blue,
|
||||
variables: THEME_BLUE_JSON,
|
||||
name: SystemThemes.Blue,
|
||||
isInitial: true,
|
||||
isInitial: Appearance.getColorScheme() === 'light',
|
||||
},
|
||||
{
|
||||
uuid: SystemThemes.Dark,
|
||||
variables: THEME_DARK_JSON,
|
||||
name: SystemThemes.Dark,
|
||||
isInitial: Appearance.getColorScheme() === 'dark',
|
||||
},
|
||||
{
|
||||
uuid: SystemThemes.Red,
|
||||
variables: THEME_RED_JSON,
|
||||
name: SystemThemes.Red,
|
||||
},
|
||||
@@ -128,10 +128,11 @@ export class StyleKit {
|
||||
variables.statusBar =
|
||||
Platform.OS === 'android' ? LIGHT_CONTENT : DARK_CONTENT;
|
||||
|
||||
this.themeData[option.name] = {
|
||||
this.themeData[option.uuid] = {
|
||||
isSystemTheme: true,
|
||||
isInitial: Boolean(option.isInitial),
|
||||
name: option.name,
|
||||
uuid: option.uuid,
|
||||
variables: variables,
|
||||
package_info: {
|
||||
dock_icon: {
|
||||
@@ -174,7 +175,10 @@ export class StyleKit {
|
||||
* If we're changing the theme for a specific mode and we're currently on
|
||||
* that mode, then activate this theme.
|
||||
*/
|
||||
if (this.currentDarkMode === currentMode && this.activeTheme !== themeId) {
|
||||
if (
|
||||
this.currentDarkMode === currentMode &&
|
||||
this.activeThemeId !== themeId
|
||||
) {
|
||||
this.activateTheme(themeId);
|
||||
}
|
||||
}
|
||||
@@ -186,17 +190,17 @@ export class StyleKit {
|
||||
* copy as the result may be modified before use.
|
||||
*/
|
||||
templateVariables() {
|
||||
return _.clone(THEME_RED_JSON);
|
||||
return _.clone(THEME_BLUE_JSON);
|
||||
}
|
||||
|
||||
private resetToSystemTheme() {
|
||||
this.activateTheme(Object.keys(this.themeData)[0]);
|
||||
}
|
||||
|
||||
async resolveInitialTheme() {
|
||||
private async resolveInitialTheme() {
|
||||
// const currentMode = Appearance.getColorScheme();
|
||||
const runDefaultTheme = () => {
|
||||
const defaultTheme = SystemThemes.Blue;
|
||||
const defaultTheme = SystemThemes.Dark;
|
||||
|
||||
// TODO: save to starege
|
||||
|
||||
@@ -231,17 +235,12 @@ export class StyleKit {
|
||||
|
||||
keyboardColorForActiveTheme() {
|
||||
return keyboardColorForTheme(
|
||||
this.findOrCreateDataForTheme(this.activeTheme!)
|
||||
this.findOrCreateDataForTheme(this.activeThemeId!)
|
||||
);
|
||||
}
|
||||
|
||||
themes() {
|
||||
// TODO: add external themes
|
||||
return this.themeData;
|
||||
}
|
||||
|
||||
isThemeActive(theme: SNTheme) {
|
||||
return this.activeTheme && theme.uuid === this.activeTheme;
|
||||
systemThemes() {
|
||||
return Object.values(this.themeData).filter(th => th.isSystemTheme);
|
||||
}
|
||||
|
||||
setActiveTheme(themeId: string) {
|
||||
@@ -250,7 +249,7 @@ export class StyleKit {
|
||||
const variables = themeData.variables;
|
||||
themeData.variables = _.merge(this.templateVariables(), variables);
|
||||
|
||||
this.activeTheme = themeId;
|
||||
this.activeThemeId = themeId;
|
||||
|
||||
this.updateDeviceForTheme(themeId);
|
||||
|
||||
@@ -312,29 +311,61 @@ export class StyleKit {
|
||||
// }
|
||||
}
|
||||
|
||||
activateExternalTheme(theme: SNTheme) {
|
||||
ThemeDownloader.get()
|
||||
.downloadTheme(theme)
|
||||
.then(variables => {
|
||||
if (!variables) {
|
||||
Alert.alert(
|
||||
'Not Available',
|
||||
'This theme is not available on mobile.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
// TODO: merge new theme style
|
||||
// if (variables !== theme.content.variables) {
|
||||
// theme.content.variables = variables;
|
||||
// theme.setDirty(true);
|
||||
// }
|
||||
});
|
||||
private async downloadTheme(theme: SNTheme) {
|
||||
let errorBlock = (error: null) => {
|
||||
console.error('Theme download error', error);
|
||||
};
|
||||
|
||||
let url = theme.hosted_url;
|
||||
|
||||
if (!url) {
|
||||
errorBlock(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Platform.OS === 'android' && url.includes('localhost')) {
|
||||
url = url.replace('localhost', '10.0.2.2');
|
||||
}
|
||||
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
// console.log(JSON.parse(response));
|
||||
const data = await response.text();
|
||||
// @ts-ignore TODO: check response type
|
||||
let variables = CSSParser.cssToObject(data);
|
||||
|
||||
resolve(variables);
|
||||
} catch (e) {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
activateSystemTheme(themeId: string) {
|
||||
this.activateTheme(themeId);
|
||||
}
|
||||
|
||||
async activateExternalTheme(theme: SNTheme) {
|
||||
const variables = await this.downloadTheme(theme);
|
||||
if (!variables) {
|
||||
Alert.alert('Not Available', 'This theme is not available on mobile.');
|
||||
return;
|
||||
}
|
||||
let data = this.findOrCreateDataForTheme(theme.uuid);
|
||||
const appliedVariables = _.merge(this.templateVariables(), variables);
|
||||
data.variables = {
|
||||
...appliedVariables,
|
||||
...StyleKit.constants,
|
||||
};
|
||||
this.activateTheme(theme.uuid);
|
||||
}
|
||||
|
||||
activateTheme(themeId: string) {
|
||||
this.setActiveTheme(themeId);
|
||||
this.assignThemeForMode(themeId);
|
||||
// this.assignThemeForMode(themeId);
|
||||
}
|
||||
|
||||
// activatePreferredTheme() {
|
||||
@@ -359,7 +390,7 @@ export class StyleKit {
|
||||
// }
|
||||
|
||||
async downloadThemeAndReload(theme: SNTheme) {
|
||||
const updatedVariables = await ThemeDownloader.get().downloadTheme(theme);
|
||||
const updatedVariables = await this.downloadTheme(theme);
|
||||
|
||||
/** Merge default variables to ensure this theme has all the variables. */
|
||||
const appliedVariables = _.merge(
|
||||
@@ -372,13 +403,13 @@ export class StyleKit {
|
||||
...StyleKit.constants,
|
||||
};
|
||||
|
||||
if (theme.uuid === this.activeTheme) {
|
||||
if (theme.uuid === this.activeThemeId) {
|
||||
this.setActiveTheme(theme.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
reloadStyles() {
|
||||
const { variables } = this.findOrCreateDataForTheme(this.activeTheme!);
|
||||
const { variables } = this.findOrCreateDataForTheme(this.activeThemeId!);
|
||||
|
||||
this.theme = variables;
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import CSSParser from '@Style/Util/CSSParser';
|
||||
import { Platform } from 'react-native';
|
||||
import { SNHttpService, SNTheme } from 'snjs';
|
||||
|
||||
export default class ThemeDownloader {
|
||||
private static instance: ThemeDownloader;
|
||||
private httpService = new SNHttpService();
|
||||
|
||||
static get() {
|
||||
if (!this.instance) {
|
||||
this.instance = new ThemeDownloader();
|
||||
}
|
||||
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
async downloadTheme(theme: SNTheme) {
|
||||
let errorBlock = (error: null) => {
|
||||
console.error('Theme download error', error);
|
||||
};
|
||||
|
||||
let url = theme.hosted_url;
|
||||
|
||||
if (!url) {
|
||||
errorBlock(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Platform.OS === 'android' && url.includes('localhost')) {
|
||||
url = url.replace('localhost', '10.0.2.2');
|
||||
}
|
||||
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
const response = await this.httpService.getAbsolute(url, {});
|
||||
// @ts-ignore TODO: check response type
|
||||
let variables = CSSParser.cssToObject(response);
|
||||
resolve(variables);
|
||||
} catch (e) {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -7023,9 +7023,9 @@ sncrypto@standardnotes/sncrypto#7e76ab9:
|
||||
version "1.1.3"
|
||||
resolved "https://codeload.github.com/standardnotes/sncrypto/tar.gz/7e76ab9977f85039d9399b935aecfe495a951edb"
|
||||
|
||||
snjs@standardnotes/snjs#84b0403:
|
||||
snjs@standardnotes/snjs#27688ba:
|
||||
version "1.0.5"
|
||||
resolved "https://codeload.github.com/standardnotes/snjs/tar.gz/84b04033e1877dbbe54a7b1e03065fa7a0044744"
|
||||
resolved "https://codeload.github.com/standardnotes/snjs/tar.gz/27688ba55aa0d50b6bd8e27caf8d7b988fde411d"
|
||||
|
||||
source-map-resolve@^0.5.0:
|
||||
version "0.5.3"
|
||||
|
||||
Reference in New Issue
Block a user