Skip to content

Commit 0a813a2

Browse files
authored
Merge pull request #2 from mathnotes-app/feat/legal-pages-review-prompt
feat: add legal pages and review prompt
2 parents a1493f1 + ec1e365 commit 0a813a2

30 files changed

Lines changed: 703 additions & 54 deletions

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ OpenNotes is designed to be local and private. The app does not include analytic
6363

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

66+
Public legal and support pages:
67+
68+
- [Privacy Policy](https://mathnotes-app.github.io/OpenNotes/privacy/)
69+
- [Terms of Use](https://mathnotes-app.github.io/OpenNotes/terms/)
70+
- [Support](https://mathnotes-app.github.io/OpenNotes/support/)
71+
6672
## Contributing
6773

6874
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.

android/app/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ android {
8787
buildToolsVersion rootProject.ext.buildToolsVersion
8888
compileSdk rootProject.ext.compileSdkVersion
8989

90-
namespace 'com.opennotes.app'
90+
namespace 'com.builderpro.opennotes'
9191
defaultConfig {
92-
applicationId 'com.opennotes.app'
92+
applicationId 'com.builderpro.opennotes'
9393
minSdkVersion rootProject.ext.minSdkVersion
9494
targetSdkVersion rootProject.ext.targetSdkVersion
95-
versionCode 1
96-
versionName "0.1.0"
95+
versionCode 6
96+
versionName "1.0"
9797

9898
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
9999
}

android/app/src/main/java/com/opennotes/app/MainActivity.kt renamed to android/app/src/main/java/com/builderpro/opennotes/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.opennotes.app
1+
package com.builderpro.opennotes
22

33
import android.os.Build
44
import android.os.Bundle

android/app/src/main/java/com/opennotes/app/MainApplication.kt renamed to android/app/src/main/java/com/builderpro/opennotes/MainApplication.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.opennotes.app
1+
package com.builderpro.opennotes
22

33
import android.app.Application
44
import android.content.res.Configuration

android/app/src/main/java/com/opennotes/app/PDFUtilsModule.kt renamed to android/app/src/main/java/com/builderpro/opennotes/PDFUtilsModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.opennotes.app
1+
package com.builderpro.opennotes
22

33
import android.graphics.pdf.PdfRenderer
44
import android.net.Uri

android/app/src/main/java/com/opennotes/app/PDFUtilsPackage.kt renamed to android/app/src/main/java/com/builderpro/opennotes/PDFUtilsPackage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.opennotes.app
1+
package com.builderpro.opennotes
22

33
import com.facebook.react.TurboReactPackage
44
import com.facebook.react.bridge.NativeModule

app.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22
"expo": {
33
"name": "OpenNotes",
44
"slug": "open-notes",
5-
"version": "0.1.0",
5+
"version": "1.0",
66
"scheme": "opennotes",
77
"orientation": "default",
8+
"icon": "./assets/icon.png",
89
"userInterfaceStyle": "automatic",
910
"newArchEnabled": true,
11+
"splash": {
12+
"image": "./assets/splash-icon.png",
13+
"resizeMode": "contain",
14+
"backgroundColor": "#F7F7F4"
15+
},
1016
"ios": {
11-
"bundleIdentifier": "com.opennotes.app",
17+
"bundleIdentifier": "com.builderpro.opennotes",
18+
"icon": "./assets/icon.png",
19+
"buildNumber": "6",
1220
"supportsTablet": true,
1321
"infoPlist": {
1422
"NSPhotoLibraryUsageDescription": "OpenNotes needs access to your photo library so you can insert images into your notes.",
@@ -45,7 +53,12 @@
4553
}
4654
},
4755
"android": {
48-
"package": "com.opennotes.app",
56+
"package": "com.builderpro.opennotes",
57+
"versionCode": 6,
58+
"adaptiveIcon": {
59+
"foregroundImage": "./assets/adaptive-icon.png",
60+
"backgroundColor": "#F7F7F4"
61+
},
4962
"permissions": [
5063
"android.permission.READ_EXTERNAL_STORAGE",
5164
"android.permission.WRITE_EXTERNAL_STORAGE",

app/folder/[id].tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
listFolders,
2727
renameFolder,
2828
} from '../../src/services/foldersRepo';
29+
import { recordReviewSignal } from '../../src/services/reviewPromptService';
2930
import type { BackgroundType, FolderMetadata, NoteMetadata } from '../../src/types/note';
3031

3132
type Action =
@@ -81,12 +82,16 @@ export default function FolderScreen() {
8182
backgroundType,
8283
title: title.trim() || undefined,
8384
});
85+
void recordReviewSignal('note_created');
8486
router.push(`/note/${meta.id}`);
8587
return;
8688
}
8789

8890
const meta = await createPdfNoteFromPicker({ folderId: folder.id, title });
89-
if (meta) router.push(`/note/${meta.id}`);
91+
if (meta) {
92+
void recordReviewSignal('note_created');
93+
router.push(`/note/${meta.id}`);
94+
}
9095
} catch (error) {
9196
if (__DEV__) console.warn('[FolderScreen] create note failed', error);
9297
Alert.alert('Could not create note', 'Please try again.');
@@ -162,7 +167,10 @@ export default function FolderScreen() {
162167
<NoteCard
163168
key={note.id}
164169
note={note}
165-
onPress={() => router.push(`/note/${note.id}`)}
170+
onPress={() => {
171+
void recordReviewSignal('note_opened');
172+
router.push(`/note/${note.id}`);
173+
}}
166174
onLongPress={() => {
167175
void Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
168176
setAction({ kind: 'noteMenu', note });

app/index.tsx

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
ActivityIndicator,
44
Alert,
55
Linking,
6+
Pressable,
67
ScrollView,
78
StyleSheet,
89
Text,
@@ -39,8 +40,20 @@ import {
3940
listFolders,
4041
renameFolder,
4142
} from '../src/services/foldersRepo';
43+
import {
44+
recordReviewSignal,
45+
requestReviewAfterPositiveMoment,
46+
} from '../src/services/reviewPromptService';
4247
import type { BackgroundType, FolderMetadata, NoteMetadata } from '../src/types/note';
4348

49+
const LEGAL_URLS = {
50+
privacy: 'https://mathnotes-app.github.io/OpenNotes/privacy/',
51+
terms: 'https://mathnotes-app.github.io/OpenNotes/terms/',
52+
support: 'https://mathnotes-app.github.io/OpenNotes/support/',
53+
github: 'https://github.com/mathnotes-app/OpenNotes',
54+
x: 'https://x.com/markpm39',
55+
};
56+
4457
type Action =
4558
| { kind: 'newItem' }
4659
| { kind: 'about' }
@@ -78,6 +91,7 @@ export default function LibraryScreen() {
7891
useFocusEffect(
7992
useCallback(() => {
8093
void refresh();
94+
void requestReviewAfterPositiveMoment();
8195
}, [refresh]),
8296
);
8397

@@ -103,6 +117,7 @@ export default function LibraryScreen() {
103117
const openNote = useCallback(
104118
(id: string) => {
105119
void Haptics.selectionAsync();
120+
void recordReviewSignal('note_opened');
106121
router.push(`/note/${id}`);
107122
},
108123
[router],
@@ -127,12 +142,16 @@ export default function LibraryScreen() {
127142
backgroundType,
128143
title: title.trim() || undefined,
129144
});
145+
void recordReviewSignal('note_created');
130146
openNote(meta.id);
131147
return;
132148
}
133149

134150
const meta = await createPdfNoteFromPicker({ folderId: null, title });
135-
if (meta) openNote(meta.id);
151+
if (meta) {
152+
void recordReviewSignal('note_created');
153+
openNote(meta.id);
154+
}
136155
} catch (error) {
137156
if (__DEV__) console.warn('[LibraryScreen] create note failed', error);
138157
Alert.alert('Could not create note', 'Please try again.');
@@ -233,13 +252,13 @@ export default function LibraryScreen() {
233252
key: 'github',
234253
icon: 'logo-github',
235254
accessibilityLabel: 'Open OpenNotes on GitHub',
236-
onPress: () => void openUrl('https://github.com/mathnotes-app/OpenNotes'),
255+
onPress: () => void openUrl(LEGAL_URLS.github),
237256
},
238257
{
239258
key: 'x',
240259
icon: 'logo-x',
241260
accessibilityLabel: 'Open Mark Miller on X',
242-
onPress: () => void openUrl('https://x.com/markpm39'),
261+
onPress: () => void openUrl(LEGAL_URLS.x),
243262
},
244263
{
245264
key: 'about',
@@ -471,6 +490,14 @@ function AboutSheet({
471490
onClose: () => void;
472491
}) {
473492
const theme = useTheme();
493+
const openUrl = useCallback(async (url: string) => {
494+
try {
495+
await Linking.openURL(url);
496+
} catch (error) {
497+
if (__DEV__) console.warn('[AboutSheet] open link failed', error);
498+
Alert.alert('Could not open link', 'Please try again.');
499+
}
500+
}, []);
474501

475502
return (
476503
<Sheet visible={visible} onClose={onClose}>
@@ -506,10 +533,34 @@ function AboutSheet({
506533
<Text style={[typography.footnote, styles.aboutBody, { color: theme.colors.textSecondary }]}>
507534
OpenNotes is powered by the open source Mobile Ink engine.
508535
</Text>
536+
<View style={styles.aboutLinks}>
537+
<AboutLink label="Privacy" onPress={() => void openUrl(LEGAL_URLS.privacy)} />
538+
<AboutLink label="Terms" onPress={() => void openUrl(LEGAL_URLS.terms)} />
539+
<AboutLink label="Support" onPress={() => void openUrl(LEGAL_URLS.support)} />
540+
</View>
509541
</Sheet>
510542
);
511543
}
512544

545+
function AboutLink({ label, onPress }: { label: string; onPress: () => void }) {
546+
const theme = useTheme();
547+
return (
548+
<Pressable
549+
accessibilityRole="link"
550+
onPress={onPress}
551+
style={({ pressed }) => [
552+
styles.aboutLink,
553+
{ borderColor: theme.colors.divider },
554+
pressed && { opacity: 0.65 },
555+
]}
556+
>
557+
<Text style={[typography.callout, styles.aboutLinkText, { color: theme.colors.accent }]}>
558+
{label}
559+
</Text>
560+
</Pressable>
561+
);
562+
}
563+
513564
function Section({
514565
title,
515566
theme,
@@ -581,4 +632,21 @@ const styles = StyleSheet.create({
581632
lineHeight: 22,
582633
marginBottom: spacing.md,
583634
},
635+
aboutLinks: {
636+
flexDirection: 'row',
637+
flexWrap: 'wrap',
638+
gap: spacing.sm,
639+
marginTop: spacing.xs,
640+
},
641+
aboutLink: {
642+
alignItems: 'center',
643+
borderRadius: 16,
644+
borderWidth: StyleSheet.hairlineWidth,
645+
minHeight: 34,
646+
justifyContent: 'center',
647+
paddingHorizontal: spacing.md,
648+
},
649+
aboutLinkText: {
650+
fontWeight: '600',
651+
},
584652
});

0 commit comments

Comments
 (0)