Skip to content

Commit 6b00053

Browse files
committed
feat: changelog improvements/fixes
- use a Modal for it/tweak the design - add a release date - i18n - ensure it actually shows up after updating the app
1 parent e073bb2 commit 6b00053

File tree

6 files changed

+158
-77
lines changed

6 files changed

+158
-77
lines changed

docs/dev/release-checklist.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- [ ] Update `versionName` and `versionCode` in `android/app/build.gradle`
1111
- [ ] Update the `version` field in the `package.json` file
1212
- [ ] Create a new file in `fastlane/metadata/android/en-US/changelogs/` - named `xyz.txt`, with `xyz` being the new `versionCode` - and note the biggest changes in the release, with a link to the full `CHANGELOG.md` entry - **this cannot exceed 500 characters**
13-
- [ ] Update `changelogParagraphs` in `src/components/sheets/ChangelogSheet.tsx` with a short summary of the changes
13+
- [ ] Update `changelogParagraphs` in `src/components/sheets/ChangelogSheet.tsx` with a short summary of the changes, and update `releaseDate` to reflect the update's release date
1414
- [ ] Write out a full changelog entry for `CHANGELOG.md` - use the previous entries as a guide for formatting
1515
- You can use `git log v[LASTVERSION]...main --format="%s (%h)"` to get a clean list of commits since the last release - this can help make sure you don't miss anything
1616
- [ ] Stage and commit these changes in a commit titled `release: x.y.z` (with `x.y.z` being the new version) - do **not** push the commit yet

i18n/strings/en.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252
"Supporter": "Donator",
5353
"Translator": "Translator"
5454
},
55+
"changelog": {
56+
"header": "Changelog for v{{version}}",
57+
"header_newly_updated": "Clerotri has been updated to v{{version}}",
58+
"released_on": "Released on {{date}}",
59+
"donate": "Donate",
60+
"see_full_changelog": "See the full changelog",
61+
"dismiss": "Dismiss"
62+
},
5563
"channel_list": {
5664
"direct_messages_header": "Direct Messages"
5765
},

src/Generic.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,9 @@ export const app = {
209209
`[FUNCTIONS] Tried to run uninitialised function openAnalyticsMenu (args: ${state}, ${blockClosing})`,
210210
);
211211
},
212-
openChangelog: (state: boolean) => {
212+
openChangelog: (state: boolean, isNewlyUpdated?: boolean) => {
213213
console.log(
214-
`[FUNCTIONS] Tried to run uninitialised function openChangelog (args: ${state})`,
214+
`[FUNCTIONS] Tried to run uninitialised function openChangelog (args: ${state}, ${isNewlyUpdated})`,
215215
);
216216
},
217217
openModActionModal: (member: MemberWithModAction | null) => {

src/LoggedInViews.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {settings} from '@clerotri/lib/settings';
1414
import {ChannelContext, ServerContext} from '@clerotri/lib/state';
1515
import {storage} from '@clerotri/lib/storage';
1616
import {CVChannel} from '@clerotri/lib/types';
17-
import {checkLastVersion, openLastChannel, sleep} from '@clerotri/lib/utils';
17+
import {checkLastVersion, openLastChannel} from '@clerotri/lib/utils';
1818

1919
export function LoggedInViews({
2020
channelNotificationSettings,
@@ -54,10 +54,7 @@ export function LoggedInViews({
5454
if (lastVersion) {
5555
if (settings.get('app.showChangelogs')) {
5656
console.log(`[APP] Opening changelog...`);
57-
// don't ask why but the sheet doesn't appear without this
58-
sleep(50).then(() => {
59-
app.openChangelog(true);
60-
});
57+
app.openChangelog(true, true);
6158
}
6259
}
6360
}

src/Modals.tsx

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ const BottomSheets = observer(() => {
154154
openOrCloseSheet(!!m, 'messageMenu');
155155
});
156156

157-
setFunction('openChangelog', (show: boolean) => {
158-
openOrCloseSheet(show, 'changelog');
159-
});
160-
161157
return (
162158
<BottomSheet sheetRef={sheetRef} onChange={handleSheetIndexChange}>
163159
{currentSheet === 'statusMenu' ? (
@@ -178,8 +174,6 @@ const BottomSheets = observer(() => {
178174
<MemberListSheet context={memberListContext} />
179175
) : currentSheet === 'messageMenu' ? (
180176
<MessageMenuSheet message={messageMenuMessage} />
181-
) : currentSheet === 'changelog' ? (
182-
<ChangelogSheet />
183177
) : null}
184178
</BottomSheet>
185179
);
@@ -421,27 +415,48 @@ export const PreLoginModals = observer(() => {
421415
useState(false);
422416
const [analyticsSettingsBlockClosing, setAnalyticsSettingsBlockClosing] =
423417
useState(false);
418+
const [changelogVisibility, setChangelogVisibility] = useState(false);
419+
const [changelogIsNewlyUpdated, setChangelogIsNewlyUpdated] = useState(false);
424420

425421
setFunction('openAnalyticsMenu', (o: boolean, blockClosing?: boolean) => {
426422
setAnalyticsSettingsBlockClosing(blockClosing || false);
427423
setAnalyticsSettingsVisibility(o);
428424
});
429425

426+
setFunction('openChangelog', (show: boolean, isNewlyUpdated?: boolean) => {
427+
setChangelogIsNewlyUpdated(isNewlyUpdated || false);
428+
setChangelogVisibility(show);
429+
});
430+
430431
return (
431-
<Modal
432-
visible={analyticsSettingsVisibility}
433-
transparent={true}
434-
animationType="fade"
435-
statusBarTranslucent
436-
navigationBarTranslucent
437-
onRequestClose={() =>
438-
app.handleAnalyticsSettingsVisibility(setAnalyticsSettingsVisibility)
439-
}>
440-
<AnalyticsSettingsSheet
441-
blockClosing={analyticsSettingsBlockClosing}
442-
setState={() => setAnalyticsSettingsVisibility(false)}
443-
/>
444-
</Modal>
432+
<>
433+
<Modal
434+
visible={analyticsSettingsVisibility}
435+
transparent={true}
436+
animationType="fade"
437+
statusBarTranslucent
438+
navigationBarTranslucent
439+
onRequestClose={() =>
440+
app.handleAnalyticsSettingsVisibility(setAnalyticsSettingsVisibility)
441+
}>
442+
<AnalyticsSettingsSheet
443+
blockClosing={analyticsSettingsBlockClosing}
444+
setState={() => setAnalyticsSettingsVisibility(false)}
445+
/>
446+
</Modal>
447+
<Modal
448+
visible={changelogVisibility}
449+
transparent={true}
450+
animationType="slide"
451+
statusBarTranslucent
452+
navigationBarTranslucent
453+
onRequestClose={() => setChangelogVisibility(false)}>
454+
<ChangelogSheet
455+
setState={() => setChangelogVisibility(false)}
456+
isNewlyUpdated={changelogIsNewlyUpdated}
457+
/>
458+
</Modal>
459+
</>
445460
);
446461
});
447462

Lines changed: 110 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {useContext, useMemo} from 'react';
22
import {View} from 'react-native';
3-
import {observer} from 'mobx-react-lite';
4-
5-
import {useSafeAreaInsets} from 'react-native-safe-area-context';
3+
import {StyleSheet} from 'react-native-unistyles';
4+
import {useTranslation} from 'react-i18next';
65

76
import {Text} from '@clerotri/components/common/atoms';
87
import {NewContextButton} from '@clerotri/components/common/buttons';
@@ -13,65 +12,127 @@ import {APP_VERSION} from '@clerotri/lib/metadata';
1312
import {commonValues, ThemeContext} from '@clerotri/lib/themes';
1413
import {openUrl} from '@clerotri/lib/utils';
1514

15+
const releaseDate = 'foo/bar/2026';
16+
1617
const changelogParagraphs = [
1718
'This release includes **better message rendering**, a bunch of styling and design improvements and a new language - French!',
1819
`Also note that **Clerotri is now on Bluesky!** Get updates and support at [**@clerotri.upryzing.app**](${BLUESKY_PROFILE}).`,
1920
];
2021

21-
export const ChangelogSheet = observer(() => {
22-
const insets = useSafeAreaInsets();
22+
const ChangelogHeader = ({isNewlyUpdated}: {isNewlyUpdated: boolean}) => {
23+
const {t} = useTranslation();
24+
25+
return (
26+
<View>
27+
<Text type={'h1'}>
28+
{t(`app.changelog.header${isNewlyUpdated ? '_newly_updated' : ''}`, {
29+
version: APP_VERSION,
30+
})}
31+
</Text>
32+
<Text useNewText colour={'foregroundSecondary'}>
33+
{t('app.changelog.released_on', {date: releaseDate})}
34+
</Text>
35+
<View style={localStyles.paragraphsContainer}>
36+
{changelogParagraphs.map((paragraph, index) => (
37+
<View key={`changelog-paragraph-${index}`}>
38+
<MarkdownView>{paragraph}</MarkdownView>
39+
</View>
40+
))}
41+
</View>
42+
</View>
43+
);
44+
};
45+
46+
const ChangelogButtons = ({setState}: {setState: (show: boolean) => void}) => {
2347
const {currentTheme} = useContext(ThemeContext);
2448

49+
const {t} = useTranslation();
50+
2551
const donateGradient = useMemo(
2652
() => generateDonateGradient(currentTheme),
2753
[currentTheme],
2854
);
2955

3056
return (
31-
<View
32-
style={{
33-
padding: commonValues.sizes.xl,
34-
paddingBlockEnd: commonValues.sizes.medium + insets.bottom,
35-
flex: 1,
36-
justifyContent: 'space-between',
37-
}}>
38-
<View style={{justifyContent: 'center'}}>
39-
<Text type={'h1'}>v{APP_VERSION}</Text>
40-
{changelogParagraphs.map((paragraph, index) => (
41-
<View
42-
key={`changelog-paragraph-${index}`}
43-
style={{marginBlockEnd: commonValues.sizes.medium}}>
44-
<MarkdownView>{paragraph}</MarkdownView>
45-
</View>
46-
))}
47-
</View>
48-
<View>
49-
<NewContextButton
50-
type={'start'}
51-
icon={{
52-
pack: 'community',
53-
name: 'heart',
54-
colour: 'accentColor',
55-
}}
56-
textString={'Donate'}
57-
style={{
58-
justifyContent: 'center',
59-
experimental_backgroundImage: [donateGradient],
60-
}}
61-
onPress={() => {
62-
openUrl(`${DONATIONS_INFO}_iac_${APP_VERSION}`);
63-
}}
64-
/>
65-
<NewContextButton
66-
type={'end'}
67-
icon={{pack: 'community', name: 'book-open-variant'}}
68-
textString={'See full changelog'}
69-
style={{justifyContent: 'center'}}
70-
onPress={() => {
71-
openUrl(CHANGELOG);
72-
}}
73-
/>
57+
<View>
58+
<NewContextButton
59+
type={'start'}
60+
icon={{
61+
pack: 'community',
62+
name: 'heart',
63+
colour: 'accentColor',
64+
}}
65+
textString={t('app.changelog.donate')}
66+
style={[
67+
localStyles.changelogButton,
68+
{experimental_backgroundImage: [donateGradient]},
69+
]}
70+
onPress={() => {
71+
openUrl(`${DONATIONS_INFO}_iac_${APP_VERSION}`);
72+
}}
73+
/>
74+
<NewContextButton
75+
type={'end'}
76+
icon={{pack: 'community', name: 'book-open-variant'}}
77+
textString={t('app.changelog.see_full_changelog')}
78+
style={[localStyles.changelogButton, localStyles.fullChangelogButton]}
79+
onPress={() => {
80+
openUrl(CHANGELOG);
81+
}}
82+
/>
83+
<NewContextButton
84+
type={'detatched'}
85+
icon={{pack: 'regular', name: 'close'}}
86+
textString={t('app.changelog.dismiss')}
87+
style={[localStyles.changelogButton, localStyles.closeButton]}
88+
onPress={() => {
89+
setState(false);
90+
}}
91+
/>
92+
</View>
93+
);
94+
};
95+
96+
export const ChangelogSheet = ({
97+
setState,
98+
isNewlyUpdated,
99+
}: {
100+
setState: (show: boolean) => void;
101+
isNewlyUpdated: boolean;
102+
}) => {
103+
return (
104+
<View style={localStyles.container}>
105+
<View style={localStyles.innerContainer}>
106+
<ChangelogHeader isNewlyUpdated={isNewlyUpdated} />
107+
<ChangelogButtons setState={setState} />
74108
</View>
75109
</View>
76110
);
77-
});
111+
};
112+
113+
const localStyles = StyleSheet.create((currentTheme, rt) => ({
114+
container: {
115+
flex: 1,
116+
padding: commonValues.sizes.xl,
117+
paddingBlockStart: commonValues.sizes.xl + rt.insets.top,
118+
paddingBlockEnd: commonValues.sizes.xl + rt.insets.bottom,
119+
backgroundColor: currentTheme.backgroundPrimary,
120+
},
121+
innerContainer: {
122+
flex: 1,
123+
justifyContent: 'space-between',
124+
},
125+
paragraphsContainer: {
126+
marginBlockStart: commonValues.sizes.large,
127+
gap: commonValues.sizes.medium,
128+
},
129+
changelogButton: {
130+
flex: 0,
131+
justifyContent: 'center',
132+
},
133+
fullChangelogButton: {
134+
backgroundColor: currentTheme.backgroundSecondary,
135+
marginBlockEnd: commonValues.sizes.xs,
136+
},
137+
closeButton: {marginBlockEnd: 0},
138+
}));

0 commit comments

Comments
 (0)