Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ OpenNotes is designed to be local and private. The app does not include analytic

If you export, share, back up, or import files through another app or operating-system service, that service's behavior is outside OpenNotes.

Public legal and support pages:

- [Privacy Policy](https://mathnotes-app.github.io/OpenNotes/privacy/)
- [Terms of Use](https://mathnotes-app.github.io/OpenNotes/terms/)
- [Support](https://mathnotes-app.github.io/OpenNotes/support/)

## Contributing

Bug reports, feature requests, and focused pull requests are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md), and please avoid attaching private notes or documents to public issues.
Expand Down
8 changes: 4 additions & 4 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ android {
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion

namespace 'com.opennotes.app'
namespace 'com.builderpro.opennotes'
defaultConfig {
applicationId 'com.opennotes.app'
applicationId 'com.builderpro.opennotes'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "0.1.0"
versionCode 6
versionName "1.0"

buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.opennotes.app
package com.builderpro.opennotes

import android.os.Build
import android.os.Bundle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.opennotes.app
package com.builderpro.opennotes

import android.app.Application
import android.content.res.Configuration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.opennotes.app
package com.builderpro.opennotes

import android.graphics.pdf.PdfRenderer
import android.net.Uri
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.opennotes.app
package com.builderpro.opennotes

import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
Expand Down
19 changes: 16 additions & 3 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
"expo": {
"name": "OpenNotes",
"slug": "open-notes",
"version": "0.1.0",
"version": "1.0",
"scheme": "opennotes",
"orientation": "default",
"icon": "./assets/icon.png",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"splash": {
"image": "./assets/splash-icon.png",
"resizeMode": "contain",
"backgroundColor": "#F7F7F4"
},
"ios": {
"bundleIdentifier": "com.opennotes.app",
"bundleIdentifier": "com.builderpro.opennotes",
"icon": "./assets/icon.png",
"buildNumber": "6",
"supportsTablet": true,
"infoPlist": {
"NSPhotoLibraryUsageDescription": "OpenNotes needs access to your photo library so you can insert images into your notes.",
Expand Down Expand Up @@ -45,7 +53,12 @@
}
},
"android": {
"package": "com.opennotes.app",
"package": "com.builderpro.opennotes",
"versionCode": 6,
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#F7F7F4"
},
"permissions": [
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
Expand Down
12 changes: 10 additions & 2 deletions app/folder/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
listFolders,
renameFolder,
} from '../../src/services/foldersRepo';
import { recordReviewSignal } from '../../src/services/reviewPromptService';
import type { BackgroundType, FolderMetadata, NoteMetadata } from '../../src/types/note';

type Action =
Expand Down Expand Up @@ -81,12 +82,16 @@ export default function FolderScreen() {
backgroundType,
title: title.trim() || undefined,
});
void recordReviewSignal('note_created');
router.push(`/note/${meta.id}`);
return;
}

const meta = await createPdfNoteFromPicker({ folderId: folder.id, title });
if (meta) router.push(`/note/${meta.id}`);
if (meta) {
void recordReviewSignal('note_created');
router.push(`/note/${meta.id}`);
}
} catch (error) {
if (__DEV__) console.warn('[FolderScreen] create note failed', error);
Alert.alert('Could not create note', 'Please try again.');
Expand Down Expand Up @@ -162,7 +167,10 @@ export default function FolderScreen() {
<NoteCard
key={note.id}
note={note}
onPress={() => router.push(`/note/${note.id}`)}
onPress={() => {
void recordReviewSignal('note_opened');
router.push(`/note/${note.id}`);
}}
onLongPress={() => {
void Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
setAction({ kind: 'noteMenu', note });
Expand Down
74 changes: 71 additions & 3 deletions app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ActivityIndicator,
Alert,
Linking,
Pressable,
ScrollView,
StyleSheet,
Text,
Expand Down Expand Up @@ -39,8 +40,20 @@ import {
listFolders,
renameFolder,
} from '../src/services/foldersRepo';
import {
recordReviewSignal,
requestReviewAfterPositiveMoment,
} from '../src/services/reviewPromptService';
import type { BackgroundType, FolderMetadata, NoteMetadata } from '../src/types/note';

const LEGAL_URLS = {
privacy: 'https://mathnotes-app.github.io/OpenNotes/privacy/',
terms: 'https://mathnotes-app.github.io/OpenNotes/terms/',
support: 'https://mathnotes-app.github.io/OpenNotes/support/',
github: 'https://github.com/mathnotes-app/OpenNotes',
x: 'https://x.com/markpm39',
};

type Action =
| { kind: 'newItem' }
| { kind: 'about' }
Expand Down Expand Up @@ -78,6 +91,7 @@ export default function LibraryScreen() {
useFocusEffect(
useCallback(() => {
void refresh();
void requestReviewAfterPositiveMoment();
}, [refresh]),
);

Expand All @@ -103,6 +117,7 @@ export default function LibraryScreen() {
const openNote = useCallback(
(id: string) => {
void Haptics.selectionAsync();
void recordReviewSignal('note_opened');
router.push(`/note/${id}`);
},
[router],
Expand All @@ -127,12 +142,16 @@ export default function LibraryScreen() {
backgroundType,
title: title.trim() || undefined,
});
void recordReviewSignal('note_created');
openNote(meta.id);
return;
}

const meta = await createPdfNoteFromPicker({ folderId: null, title });
if (meta) openNote(meta.id);
if (meta) {
void recordReviewSignal('note_created');
openNote(meta.id);
}
} catch (error) {
if (__DEV__) console.warn('[LibraryScreen] create note failed', error);
Alert.alert('Could not create note', 'Please try again.');
Expand Down Expand Up @@ -233,13 +252,13 @@ export default function LibraryScreen() {
key: 'github',
icon: 'logo-github',
accessibilityLabel: 'Open OpenNotes on GitHub',
onPress: () => void openUrl('https://github.com/mathnotes-app/OpenNotes'),
onPress: () => void openUrl(LEGAL_URLS.github),
},
{
key: 'x',
icon: 'logo-x',
accessibilityLabel: 'Open Mark Miller on X',
onPress: () => void openUrl('https://x.com/markpm39'),
onPress: () => void openUrl(LEGAL_URLS.x),
},
{
key: 'about',
Expand Down Expand Up @@ -471,6 +490,14 @@ function AboutSheet({
onClose: () => void;
}) {
const theme = useTheme();
const openUrl = useCallback(async (url: string) => {
try {
await Linking.openURL(url);
} catch (error) {
if (__DEV__) console.warn('[AboutSheet] open link failed', error);
Alert.alert('Could not open link', 'Please try again.');
}
}, []);

return (
<Sheet visible={visible} onClose={onClose}>
Expand Down Expand Up @@ -506,10 +533,34 @@ function AboutSheet({
<Text style={[typography.footnote, styles.aboutBody, { color: theme.colors.textSecondary }]}>
OpenNotes is powered by the open source Mobile Ink engine.
</Text>
<View style={styles.aboutLinks}>
<AboutLink label="Privacy" onPress={() => void openUrl(LEGAL_URLS.privacy)} />
<AboutLink label="Terms" onPress={() => void openUrl(LEGAL_URLS.terms)} />
<AboutLink label="Support" onPress={() => void openUrl(LEGAL_URLS.support)} />
</View>
</Sheet>
);
}

function AboutLink({ label, onPress }: { label: string; onPress: () => void }) {
const theme = useTheme();
return (
<Pressable
accessibilityRole="link"
onPress={onPress}
style={({ pressed }) => [
styles.aboutLink,
{ borderColor: theme.colors.divider },
pressed && { opacity: 0.65 },
]}
>
<Text style={[typography.callout, styles.aboutLinkText, { color: theme.colors.accent }]}>
{label}
</Text>
</Pressable>
);
}

function Section({
title,
theme,
Expand Down Expand Up @@ -581,4 +632,21 @@ const styles = StyleSheet.create({
lineHeight: 22,
marginBottom: spacing.md,
},
aboutLinks: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: spacing.sm,
marginTop: spacing.xs,
},
aboutLink: {
alignItems: 'center',
borderRadius: 16,
borderWidth: StyleSheet.hairlineWidth,
minHeight: 34,
justifyContent: 'center',
paddingHorizontal: spacing.md,
},
aboutLinkText: {
fontWeight: '600',
},
});
Loading
Loading