mobile: share extension cleanup

This commit is contained in:
Ammar Ahmed
2023-11-30 12:20:22 +05:00
committed by Abdullah Atta
parent d5ee925c52
commit 528fb3092b
10 changed files with 114 additions and 394 deletions

View File

@@ -143,7 +143,6 @@ export const Button = ({
{!title ? null : (
<Component
animated={false}
color={textColor as string}
size={fontSize}
numberOfLines={1}

View File

@@ -27,8 +27,7 @@ import {
View,
ViewStyle
} from "react-native";
import Animated from "react-native-reanimated";
import { hexToRGBA, RGB_Linear_Shade } from "../../../utils/colors";
import { RGB_Linear_Shade, hexToRGBA } from "../../../utils/colors";
import { br } from "../../../utils/size";
export interface PressableButtonProps extends PressableProps {
customStyle?: ViewStyle;
@@ -41,7 +40,6 @@ export interface PressableButtonProps extends PressableProps {
customAlpha?: number;
customOpacity?: number;
fwdRef?: RefObject<View>;
animatedViewProps?: Animated.AnimateProps<View>;
hidden?: boolean;
}

View File

@@ -17,24 +17,16 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useMemo } from "react";
import { Platform, Text, TextProps, ViewStyle } from "react-native";
import Animated, {
ComplexAnimationBuilder,
Layout
} from "react-native-reanimated";
import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { Platform, Text, TextProps, ViewStyle } from "react-native";
import { SIZE } from "../../../utils/size";
interface HeadingProps extends TextProps {
color?: string;
size?: number;
layout?: ComplexAnimationBuilder;
animated?: boolean;
extraBold?: boolean;
}
const AnimatedText = Animated.createAnimatedComponent(Text);
const extraBoldStyle = {
fontFamily: Platform.OS === "android" ? "OpenSans-Bold" : undefined,
fontWeight: Platform.OS === "ios" ? "800" : undefined
@@ -48,16 +40,13 @@ const Heading = ({
color,
size = SIZE.xl,
style,
animated,
extraBold,
...restProps
}: HeadingProps) => {
const { colors } = useThemeColors();
const Component = useMemo(() => (animated ? AnimatedText : Text), [animated]);
return (
<Component
layout={restProps.layout || Layout}
<Text
allowFontScaling={true}
{...restProps}
style={[
@@ -68,7 +57,7 @@ const Heading = ({
extraBold ? (extraBoldStyle as ViewStyle) : (boldStyle as ViewStyle),
style
]}
></Component>
></Text>
);
};

View File

@@ -17,34 +17,24 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useMemo } from "react";
import { Text, TextProps } from "react-native";
import Animated, {
ComplexAnimationBuilder,
Layout
} from "react-native-reanimated";
import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { Text, TextProps } from "react-native";
import { SIZE } from "../../../utils/size";
interface ParagraphProps extends TextProps {
color?: string;
size?: number;
layout?: ComplexAnimationBuilder;
animated?: boolean;
}
const AnimatedText = Animated.createAnimatedComponent(Text);
const Paragraph = ({
color,
size = SIZE.sm,
style,
animated,
...restProps
}: ParagraphProps) => {
const { colors } = useThemeColors();
const Component = useMemo(() => (animated ? AnimatedText : Text), [animated]);
return (
<Component
layout={restProps.layout || Layout}
<Text
{...restProps}
style={[
{

View File

@@ -10,10 +10,10 @@ const ShareProvider = () => {
NotesnookShare = require('../share/index').default;
return Platform.OS === 'ios' ? (
<SafeAreaProvider>
<NotesnookShare quicknote={false} />
<NotesnookShare />
</SafeAreaProvider>
) : (
<NotesnookShare quicknote={false} />
<NotesnookShare />
);
};

View File

@@ -53,17 +53,4 @@ const ShareProvider = () => {
);
};
AppRegistry.registerComponent('NotesnookShare', () => ShareProvider);
const QuickNoteProvider = () => {
QuickNoteIOS = require('../share/quick-note').default;
return (
<SafeAreaProvider>
<QuickNoteIOS />
</SafeAreaProvider>
);
};
AppRegistry.registerComponent('QuickNoteIOS', () => QuickNoteProvider);
AppRegistry.registerComponent('NotesnookShare', () => ShareProvider);

View File

@@ -1,35 +0,0 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from "react";
import RNBootSplash from "react-native-bootsplash";
export default class QuickNoteIOS extends Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
RNBootSplash.hide({ fade: true });
}
render() {
return null;
}
}

View File

@@ -32,13 +32,13 @@ import {
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import create from "zustand";
import { db } from "../app/common/database";
import Paragraph from "../app/components/ui/typography/paragraph";
import { useDBItem } from "../app/hooks/use-db-item";
import { useNotebook } from "../app/hooks/use-notebook";
import { getElevationStyle } from "../app/utils/elevation";
import { initDatabase, useShareStore } from "./store";
import { createItemSelectionStore } from "../app/stores/item-selection-store";
import create from "zustand";
export const useNotebookExpandedStore = create<{
expanded: {
@@ -211,7 +211,7 @@ const NotebookItem = ({
flexDirection: "column"
}}
>
<Text
<Paragraph
numberOfLines={1}
style={{
color: colors.primary.paragraph,
@@ -219,7 +219,7 @@ const NotebookItem = ({
}}
>
{notebook.title}
</Text>
</Paragraph>
</View>
</View>
@@ -314,7 +314,7 @@ const ListItem = ({
flexDirection: "column"
}}
>
<Text
<Paragraph
numberOfLines={1}
style={{
color: colors.primary.paragraph,
@@ -323,7 +323,7 @@ const ListItem = ({
>
{item.type === "tag" ? "#" : ""}
{item.title}
</Text>
</Paragraph>
</View>
</View>
</TouchableOpacity>
@@ -333,12 +333,10 @@ const ListItem = ({
export const Search = ({
close,
getKeyboardHeight,
quicknote,
mode
}: {
close?: () => void;
getKeyboardHeight: () => number;
quicknote?: boolean;
mode: SearchMode;
}) => {
const { colors } = useThemeColors();
@@ -405,12 +403,6 @@ export const Search = ({
[close, mode, items]
);
const customStyles = quicknote
? {
marginTop: -(insets.top || 0),
paddingTop: insets.top
}
: {};
const searchHeight = height - getKeyboardHeight();
return (
<View
@@ -418,14 +410,13 @@ export const Search = ({
position: "absolute",
top: Platform.OS === "android" ? 20 : 0,
backgroundColor: colors.primary.background,
borderRadius: quicknote ? 0 : 10,
width: quicknote ? "100%" : "95%",
borderRadius: 10,
width: "95%",
minHeight: 250,
alignSelf: "center",
overflow: "hidden",
zIndex: 999,
...getElevationStyle(quicknote ? 1 : 5),
...customStyles
...getElevationStyle(5)
}}
>
<View
@@ -498,7 +489,7 @@ export const Search = ({
checkQueryExists(searchKeyword);
}}
>
<Text
<Paragraph
numberOfLines={1}
style={{
color: colors.primary.paragraph,
@@ -506,7 +497,7 @@ export const Search = ({
}}
>
Add #{searchKeyword}
</Text>
</Paragraph>
</TouchableOpacity>
) : null}

View File

@@ -47,11 +47,16 @@ import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import isURL from "validator/lib/isURL";
import { db } from "../app/common/database";
import Storage from "../app/common/database/storage";
import { Button } from "../app/components/ui/button";
import Heading from "../app/components/ui/typography/heading";
import Paragraph from "../app/components/ui/typography/paragraph";
import { useDBItem } from "../app/hooks/use-db-item";
import { eSendEvent } from "../app/services/event-manager";
import { FILE_SIZE_LIMIT, IMAGE_SIZE_LIMIT } from "../app/utils/constants";
import { getElevationStyle } from "../app/utils/elevation";
import { eOnLoadNote } from "../app/utils/events";
import { NoteBundle } from "../app/utils/note-bundle";
import { SIZE } from "../app/utils/size";
import { AddNotebooks } from "./add-notebooks";
import { AddTags } from "./add-tags";
import { Editor } from "./editor";
@@ -110,7 +115,7 @@ const modes = {
}
};
const ShareView = ({ quicknote = false }) => {
const ShareView = () => {
const { colors } = useThemeColors();
const appendNote = useShareStore((state) => state.appendNote);
const [note, setNote] = useState({ ...defaultNote });
@@ -251,11 +256,7 @@ const ShareView = ({ quicknote = false }) => {
const close = async () => {
setNote({ ...defaultNote });
setLoadingExtension(true);
if (quicknote) {
ShareExtension.openURL("ShareMedia://MainApp");
} else {
ShareExtension.close();
}
ShareExtension.close();
};
const onPress = async () => {
@@ -368,99 +369,41 @@ const ShareView = ({ quicknote = false }) => {
<SafeAreaView
style={{
width: width > 500 ? 500 : width,
height: quicknote ? height : height - kh,
height: height - kh,
alignSelf: "center",
justifyContent: quicknote ? "flex-start" : "flex-end"
justifyContent: "flex-end"
}}
>
{loadingPage ? <HtmlLoadingWebViewAgent /> : null}
{quicknote && !searchMode ? (
<TouchableOpacity
activeOpacity={1}
onPress={() => {
if (searchMode) {
setSearchMode(null);
} else {
close();
}
}}
style={{
width: "100%",
height: "100%",
position: "absolute"
}}
>
<View
style={{
width: "100%",
backgroundColor: colors.primary.background,
height: 50 + insets.top,
paddingTop: insets.top,
...getElevationStyle(1),
marginTop: -insets.top,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
}}
>
<Button
type="action"
icon="close"
iconColor={colors.secondary.icon}
onPress={() => {
if (searchMode) {
setSearchMode(null);
} else {
close();
}
}}
style={{
width: 50,
height: 50,
marginBottom: 0
}}
iconSize={25}
/>
<Text
style={{
color: colors.primary.paragraph,
fontSize: 17
}}
>
Quick note
</Text>
<Button
type="action"
icon="check"
iconColor={colors.primary.accent}
onPress={onPress}
style={{
width: 50,
height: 50,
marginBottom: 0
}}
iconSize={25}
/>
</View>
) : (
<TouchableOpacity
activeOpacity={1}
onPress={() => {
if (searchMode) {
setSearchMode(null);
} else {
close();
}
}}
style={{
width: "100%",
height: "100%",
position: "absolute"
backgroundColor: "white",
opacity: 0.01
}}
>
<View
style={{
width: "100%",
height: "100%",
backgroundColor: "white",
opacity: 0.01
}}
/>
<View />
</TouchableOpacity>
)}
/>
<View />
</TouchableOpacity>
{searchMode ? (
<Search
quicknote={quicknote}
getKeyboardHeight={() => keyboardHeight.current}
mode={searchMode}
close={() => {
@@ -482,7 +425,6 @@ const ShareView = ({ quicknote = false }) => {
<View
style={{
maxHeight: "100%"
//paddingHorizontal: 12
}}
>
<View
@@ -508,32 +450,12 @@ const ShareView = ({ quicknote = false }) => {
paddingHorizontal: 12
}}
>
<Text
style={{
fontSize: 18,
fontWeight: "bold",
color: colors.primary.heading
}}
>
Save to Notesnook
</Text>
<Heading size={SIZE.lg}>Save to Notesnook</Heading>
<Button
title="Done"
style={{
backgroundColor: colors.primary.accent,
height: Platform.OS === "ios" ? 35 : 40,
paddingHorizontal: 15,
marginBottom: 0
}}
type="accent"
loading={loading}
iconColor={colors.primary.accentForeground}
onPress={onPress}
textColor={colors.primary.accentForeground}
textStyle={{
fontSize: 16,
marginLeft: 0
}}
/>
</View>
@@ -545,11 +467,12 @@ const ShareView = ({ quicknote = false }) => {
backgroundColor: colors.secondary.background
}}
>
<Text
style={{ color: colors.primary.paragraph, marginBottom: 6 }}
<Paragraph
style={{ marginBottom: 6 }}
color={colors.primary.paragraph}
>
Attaching {rawFiles.length} file(s):
</Text>
</Paragraph>
<ScrollView horizontal>
{rawFiles.map((item) =>
isImage(item.type) ? (
@@ -602,30 +525,30 @@ const ShareView = ({ quicknote = false }) => {
name="file"
/>
<Text
<Paragraph
size={SIZE.xs}
color={colors.primary.paragraph}
style={{
marginLeft: 4,
color: colors.primary.paragraph,
paddingRight: 8,
fontSize: 12
paddingRight: 8
}}
>
{item.name} ({formatBytes(item.size)})
</Text>
</Paragraph>
</TouchableOpacity>
)
)}
</ScrollView>
<Text
<Paragraph
color={colors.secondary.paragraph}
size={SIZE.xs}
style={{
color: colors.secondary.paragraph,
marginTop: 6,
fontSize: 11
marginTop: 6
}}
>
Tap to remove an attachment.
</Text>
</Paragraph>
</View>
) : null}
<View
@@ -658,7 +581,7 @@ const ShareView = ({ quicknote = false }) => {
{loadingPage ? (
<>
<ActivityIndicator color={colors.primary.accent} />
<Text>Preparing web clip...</Text>
<Paragraph>Preparing web clip...</Paragraph>
</>
) : null}
</>
@@ -666,28 +589,7 @@ const ShareView = ({ quicknote = false }) => {
</SafeAreaProvider>
</View>
{appendNote ? (
<Text
style={{
fontSize: 12,
color: colors.secondary.paragraph,
paddingHorizontal: 12,
marginBottom: 10,
flexWrap: "wrap"
}}
>
Above content will append to{" "}
<Text
style={{
color: colors.primary.accent,
fontWeight: "bold"
}}
>
{`"${appendNote.title}"`}
</Text>{" "}
. Click on {'"New note"'} to create a new note.
</Text>
) : null}
{appendNote ? <AppendNote id={appendNote} /> : null}
<View
style={{
@@ -697,50 +599,34 @@ const ShareView = ({ quicknote = false }) => {
alignItems: "center"
}}
>
<Text
<Paragraph
style={{
color: colors.primary.paragraph,
marginRight: 10
}}
>
Clip Mode:
</Text>
</Paragraph>
{rawData.value && isURL(rawData.value) ? (
<Button
color="transparent"
type={mode === 2 ? "inverted" : "transparent"}
icon={mode === 2 ? "radiobox-marked" : "radiobox-blank"}
onPress={() => changeMode(2)}
title={modes[2].title}
iconSize={16}
fontSize={14}
iconColor={
mode == 2 ? colors.primary.accent : colors.secondary.icon
}
textColor={
mode == 2 ? colors.primary.accent : colors.secondary.icon
}
height={30}
style={{
paddingHorizontal: 0,
height: 30,
marginRight: 12,
marginBottom: 0
paddingHorizontal: 6
}}
/>
) : null}
<Button
color="transparent"
type={mode === 1 ? "inverted" : "transparent"}
icon={mode === 1 ? "radiobox-marked" : "radiobox-blank"}
onPress={() => changeMode(1)}
onPress={() => changeMode(2)}
title={modes[1].title}
iconSize={16}
fontSize={14}
iconColor={
mode == 1 ? colors.primary.accent : colors.secondary.icon
}
textColor={
mode == 1 ? colors.primary.accent : colors.secondary.icon
}
style={{ paddingHorizontal: 0, height: 30, marginBottom: 0 }}
height={30}
style={{
paddingHorizontal: 6
}}
/>
</View>
</View>
@@ -754,27 +640,17 @@ const ShareView = ({ quicknote = false }) => {
marginTop: 10,
alignSelf: "center",
alignItems: "center",
paddingHorizontal: 12
paddingHorizontal: 12,
gap: 10
}}
>
<Button
color={colors.primary.background}
icon="plus"
onPress={() => {
useShareStore.getState().setAppendNote(null);
}}
icon="plus"
iconSize={18}
iconColor={
!appendNote ? colors.primary.accent : colors.secondary.icon
}
type={!appendNote ? "transparent" : "gray"}
title="New note"
textColor={
!appendNote ? colors.primary.accent : colors.secondary.icon
}
type="button"
textStyle={{
fontSize: 15
}}
style={{
paddingHorizontal: 12,
height: 45,
@@ -787,21 +663,12 @@ const ShareView = ({ quicknote = false }) => {
/>
<Button
color={colors.primary.bg}
icon="text-short"
onPress={() => {
setSearchMode("appendNote");
}}
icon="text-short"
iconSize={18}
iconColor={
appendNote ? colors.primary.accent : colors.secondary.icon
}
type={appendNote ? "transparent" : "gray"}
title={`Append to a note`}
textColor={colors.secondary.paragraph}
type="button"
textStyle={{
fontSize: 15
}}
style={{
paddingHorizontal: 12,
height: 45,
@@ -841,98 +708,32 @@ const ShareView = ({ quicknote = false }) => {
);
};
const Button = ({
title,
onPress,
color,
loading,
style,
textStyle,
icon,
iconSize = 22,
type = "button",
iconColor = "gray",
textColor = "white",
fontSize = 18
}) => {
const types = {
action: {
style: {
width: 60,
height: 60,
borderRadius: 100,
minWidth: 0,
paddingHorizontal: 0
},
textStyle: {}
},
button: {
style: {
height: 50,
borderRadius: 5,
justifyContent: "center",
alignItems: "center",
flexDirection: "row",
const AppendNote = ({ id }) => {
const { colors } = useThemeColors();
const [item] = useDBItem(id, "note");
return !item ? null : (
<Paragraph
size={SIZE.xs}
color={colors.secondary.paragraph}
style={{
paddingHorizontal: 12,
marginBottom: 10,
paddingHorizontal: 20
},
textStyle: {}
},
rounded: {
style: {
marginRight: 15,
height: 30,
borderRadius: 100,
paddingHorizontal: 6,
marginTop: -2.5
},
textStyle: {
fontSize: 12,
marginLeft: 5
}
}
};
return (
<TouchableOpacity
onPress={onPress}
activeOpacity={0.8}
style={[
{
backgroundColor: color,
height: 50,
borderRadius: 5,
justifyContent: "center",
alignItems: "center",
flexDirection: "row",
marginBottom: 10,
paddingHorizontal: 20
},
{ ...types[type].style, ...style }
]}
flexWrap: "wrap"
}}
>
{loading ? <ActivityIndicator color={iconColor} /> : null}
{icon && !loading ? (
<Icon name={icon} size={iconSize} color={iconColor || "white"} />
) : null}
{title ? (
<Text
style={[
{
fontSize: fontSize || 18,
color: textColor,
marginLeft: loading ? 10 : 5
},
types[type].textStyle,
textStyle
]}
>
{title}
</Text>
) : null}
</TouchableOpacity>
Above content will append to{" "}
<Paragraph
size={SIZE.xs}
style={{
color: colors.primary.accent,
fontWeight: "bold"
}}
>
{`"${item.title}"`}
</Paragraph>{" "}
. Click on {'"New note"'} to create a new note.
</Paragraph>
);
};

View File

@@ -61,9 +61,9 @@ useThemeEngineStore.getState().setTheme(currentTheme);
export const useShareStore = create((set) => ({
theme: currentTheme,
appendNote: null,
setAppendNote: (note) => {
MMKV.setItem(StorageKeys.appendNote, JSON.stringify(note));
set({ appendNote: note });
setAppendNote: (noteId) => {
MMKV.setItem(StorageKeys.appendNote, noteId);
set({ appendNote: noteId });
},
restore: () => {
let appendNote = MMKV.getString(StorageKeys.appendNote);
@@ -71,7 +71,7 @@ export const useShareStore = create((set) => ({
let selectedTags = MMKV.getString(StorageKeys.selectedTag);
appendNote = JSON.parse(appendNote);
set({
appendNote: appendNote ? JSON.parse(appendNote) : null,
appendNote: appendNote,
selectedNotebooks: selectedNotebooks ? JSON.parse(selectedNotebooks) : [],
selectedTag: selectedTags ? JSON.parse(selectedTags) : []
});