Skip to content

Commit d8a10a6

Browse files
committed
Adding functionality to let users specify their own package name (for Android Java builds) as well as the app name.
Simplified form field state while keeping UI snappy (making use of useDeferredValue). Preferred replaceAll with plain old strings rather than RegExps. Latter probably overkill and harder to read when constructing more elaborate search strings for package substitution code.
1 parent b4ccae7 commit d8a10a6

File tree

9 files changed

+213
-44
lines changed

9 files changed

+213
-44
lines changed

src/__tests__/utils.spec.js

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { PACKAGE_NAMES } from '../constants'
22
import '../releases/__mocks__/index'
3-
import { getVersionsContentInDiff, getChangelogURL } from '../utils'
3+
import {
4+
getVersionsContentInDiff,
5+
replaceAppDetails,
6+
getChangelogURL,
7+
} from '../utils'
48

59
describe('getVersionsContentInDiff', () => {
610
it('returns the versions in the provided range', () => {
@@ -65,3 +69,66 @@ describe('getChangelogURL', () => {
6569
expect(getChangelogURL({ packageName, version })).toEqual(url)
6670
})
6771
})
72+
73+
describe('replaceAppDetails ', () => {
74+
test.each([
75+
// Don't change anything if no app name or package is passed.
76+
[
77+
'RnDiffApp/ios/RnDiffApp/main.m',
78+
'',
79+
'',
80+
'RnDiffApp/ios/RnDiffApp/main.m',
81+
],
82+
[
83+
'android/app/src/debug/java/com/rndiffapp/ReactNativeFlipper.java',
84+
'',
85+
'',
86+
'android/app/src/debug/java/com/rndiffapp/ReactNativeFlipper.java',
87+
],
88+
[
89+
'location = "group:RnDiffApp.xcodeproj">',
90+
'',
91+
'',
92+
'location = "group:RnDiffApp.xcodeproj">',
93+
],
94+
// Update Java file path with correct app name and package.
95+
[
96+
'android/app/src/debug/java/com/rndiffapp/ReactNativeFlipper.java',
97+
'SuperApp',
98+
'au.org.mycorp',
99+
'android/app/src/debug/java/au/org/mycorp/superapp/ReactNativeFlipper.java',
100+
],
101+
// Update the app details in file contents.
102+
[
103+
'location = "group:RnDiffApp.xcodeproj">',
104+
'MyFancyApp',
105+
'',
106+
'location = "group:MyFancyApp.xcodeproj">',
107+
],
108+
[
109+
'applicationId "com.rndiffapp"',
110+
'ACoolApp',
111+
'net.foobar',
112+
'applicationId "net.foobar.acoolapp"',
113+
],
114+
// Don't accidentally pick up other instances of "com" such as in domain
115+
// names, or android or facebook packages.
116+
[
117+
'apply plugin: "com.android.application"',
118+
'ACoolApp',
119+
'net.foobar',
120+
'apply plugin: "com.android.application"',
121+
],
122+
[
123+
'* https://github.com/facebook/react-native',
124+
'ACoolApp',
125+
'net.foobar',
126+
'* https://github.com/facebook/react-native',
127+
],
128+
])(
129+
'replaceAppDetails("%s", "%s", "%s") -> %s',
130+
(path, appName, appPackage, newPath) => {
131+
expect(replaceAppDetails(path, appName, appPackage)).toEqual(newPath)
132+
}
133+
)
134+
})

src/components/common/CopyFileButton.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState } from 'react'
22
import styled from '@emotion/styled'
33
import { Button, Popover } from 'antd'
4-
import { getBinaryFileURL, replaceWithProvidedAppName } from '../../utils'
4+
import { getBinaryFileURL, replaceAppDetails } from '../../utils'
55
import { CopyOutlined } from '@ant-design/icons'
66

77
const popoverContentOpts = {
@@ -10,15 +10,15 @@ const popoverContentOpts = {
1010
}
1111

1212
const CopyFileButton = styled(
13-
({ open, version, path, packageName, appName, ...props }) => {
13+
({ open, version, path, packageName, appName, appPackage, ...props }) => {
1414
const [popoverContent, setPopoverContent] = useState(
1515
popoverContentOpts.default
1616
)
1717

1818
const fetchContent = () =>
1919
fetch(getBinaryFileURL({ packageName, version, path }))
2020
.then((response) => response.text())
21-
.then((content) => replaceWithProvidedAppName(content, appName))
21+
.then((content) => replaceAppDetails(content, appName, appPackage))
2222

2323
const copyContent = () => {
2424
// From https://wolfgangrittner.dev/how-to-use-clipboard-api-in-firefox/

src/components/common/Diff/Diff.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from 'react-diff-view'
1010
import DiffHeader from './DiffHeader'
1111
import { getComments } from './DiffComment'
12-
import { replaceWithProvidedAppName } from '../../../utils'
12+
import { replaceAppDetails } from '../../../utils'
1313

1414
const copyPathPopoverContentOpts = {
1515
default: 'Click to copy file path',
@@ -102,6 +102,7 @@ const Diff = ({
102102
setAllCollapsed,
103103
diffViewStyle,
104104
appName,
105+
appPackage,
105106
}) => {
106107
const [isDiffCollapsed, setIsDiffCollapsed] = useState(
107108
isDiffCollapsedByDefault({ type, hunks })
@@ -123,20 +124,21 @@ const Diff = ({
123124

124125
const getHunksWithAppName = useCallback(
125126
(originalHunks) => {
126-
if (!appName) {
127+
if (!appName && !appPackage) {
128+
// No patching of rn-diff-purge output required.
127129
return originalHunks
128130
}
129131

130132
return originalHunks.map((hunk) => ({
131133
...hunk,
132134
changes: hunk.changes.map((change) => ({
133135
...change,
134-
content: replaceWithProvidedAppName(change.content, appName),
136+
content: replaceAppDetails(change.content, appName, appPackage),
135137
})),
136-
content: replaceWithProvidedAppName(hunk.content, appName),
138+
content: replaceAppDetails(hunk.content, appName, appPackage),
137139
}))
138140
},
139-
[appName]
141+
[appName, appPackage]
140142
)
141143

142144
if (areAllCollapsed !== undefined && areAllCollapsed !== isDiffCollapsed) {
@@ -178,6 +180,7 @@ const Diff = ({
178180
resetCopyPathPopoverContent={handleResetCopyPathPopoverContent}
179181
onCompleteDiff={onCompleteDiff}
180182
appName={appName}
183+
appPackage={appPackage}
181184
diffComments={diffComments}
182185
packageName={packageName}
183186
/>
@@ -226,6 +229,7 @@ const arePropsEqual = (prevProps, nextProps) =>
226229
prevProps.isDiffCompleted === nextProps.isDiffCompleted &&
227230
prevProps.areAllCollapsed === nextProps.areAllCollapsed &&
228231
prevProps.diffViewStyle === nextProps.diffViewStyle &&
229-
prevProps.appName === nextProps.appName
232+
prevProps.appName === nextProps.appName &&
233+
prevProps.appPackage === nextProps.appPackage
230234

231235
export default React.memo(Diff, arePropsEqual)

src/components/common/Diff/DiffHeader.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,17 @@ const DiffHeader = ({
243243
copyPathPopoverContent,
244244
resetCopyPathPopoverContent,
245245
appName,
246+
appPackage,
246247
diffComments,
247248
packageName,
248249
...props
249250
}) => {
250-
const sanitizedFilePaths = getFilePathsToShow({ oldPath, newPath, appName })
251+
const sanitizedFilePaths = getFilePathsToShow({
252+
oldPath,
253+
newPath,
254+
appName,
255+
appPackage,
256+
})
251257

252258
const id = React.useMemo(
253259
() => generatePathId(oldPath, newPath),
@@ -308,6 +314,7 @@ const DiffHeader = ({
308314
path={newPath}
309315
packageName={packageName}
310316
appName={appName}
317+
appPackage={appPackage}
311318
/>
312319
<DownloadFileButton
313320
open={!hasDiff && type !== 'delete'}

src/components/common/Diff/DiffSection.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const DiffSection = ({
2525
onToggleChangeSelection,
2626
diffViewStyle,
2727
appName,
28+
appPackage,
2829
doneTitleRef,
2930
}) => {
3031
const [areAllCollapsed, setAllCollapsed] = useState(undefined)
@@ -86,6 +87,7 @@ const DiffSection = ({
8687
areAllCollapsed={areAllCollapsed}
8788
setAllCollapsed={setAllCollapsed}
8889
appName={appName}
90+
appPackage={appPackage}
8991
/>
9092
)
9193
})}

src/components/common/DiffViewer.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const DiffViewer = ({
5959
selectedChanges,
6060
onToggleChangeSelection,
6161
appName,
62+
appPackage,
6263
}) => {
6364
const { isLoading, isDone, diff } = useFetchDiff({
6465
shouldShowDiff,
@@ -197,6 +198,7 @@ const DiffViewer = ({
197198
fromVersion={fromVersion}
198199
toVersion={toVersion}
199200
appName={appName}
201+
appPackage={appPackage}
200202
packageName={packageName}
201203
/>
202204

@@ -212,6 +214,7 @@ const DiffViewer = ({
212214
isDoneSection={false}
213215
diffViewStyle={diffViewStyle}
214216
appName={appName}
217+
appPackage={appPackage}
215218
/>
216219

217220
{renderUpgradeDoneMessage({ diff, completedDiffs })}
@@ -222,6 +225,7 @@ const DiffViewer = ({
222225
isDoneSection={true}
223226
title="Done"
224227
appName={appName}
228+
appPackage={appPackage}
225229
doneTitleRef={doneTitleRef}
226230
/>
227231
</motion.div>

src/components/pages/Home.js

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useEffect } from 'react'
1+
import React, { useState, useEffect, useDeferredValue } from 'react'
22
import styled from '@emotion/styled'
33
import { Card, Input, Typography } from 'antd'
44
import GitHubButton from 'react-github-btn'
@@ -10,7 +10,11 @@ import logo from '../../assets/logo.svg'
1010
import { SHOW_LATEST_RCS } from '../../utils'
1111
import { useGetLanguageFromURL } from '../../hooks/get-language-from-url'
1212
import { useGetPackageNameFromURL } from '../../hooks/get-package-name-from-url'
13-
import { DEFAULT_APP_NAME, PACKAGE_NAMES } from '../../constants'
13+
import {
14+
DEFAULT_APP_NAME,
15+
DEFAULT_APP_PACKAGE,
16+
PACKAGE_NAMES,
17+
} from '../../constants'
1418
import { TroubleshootingGuidesButton } from '../common/TroubleshootingGuidesButton'
1519
import { updateURL } from '../../utils/update-url'
1620
import { deviceSizes } from '../../utils/device-sizes'
@@ -59,6 +63,34 @@ const TitleContainer = styled.div`
5963
margin-bottom: 8px;
6064
`
6165

66+
const AppNameField = styled.div`
67+
width: 100%;
68+
69+
@media ${deviceSizes.tablet} {
70+
padding-right: 5px;
71+
}
72+
`
73+
74+
const AppPackageField = styled.div`
75+
width: 100%;
76+
77+
@media ${deviceSizes.tablet} {
78+
padding-left: 5px;
79+
}
80+
`
81+
82+
const AppDetailsContainer = styled.div`
83+
display: flex;
84+
flex-direction: column;
85+
justify-content: space-between;
86+
gap: 15px;
87+
88+
@media ${deviceSizes.tablet} {
89+
flex-direction: row;
90+
gap: 0;
91+
}
92+
`
93+
6294
const SettingsContainer = styled.div`
6395
display: flex;
6496
align-items: center;
@@ -91,10 +123,12 @@ const Home = () => {
91123
[`${SHOW_LATEST_RCS}`]: false,
92124
})
93125

94-
const [appName, setAppName] = useState({
95-
input: '',
96-
diff: DEFAULT_APP_NAME,
97-
})
126+
const [appName, setAppName] = useState('')
127+
const [appPackage, setAppPackage] = useState('')
128+
129+
// Avoid UI lag when typing.
130+
const deferredAppName = useDeferredValue(appName)
131+
const deferredAppPackage = useDeferredValue(appPackage)
98132

99133
const homepageUrl = process.env.PUBLIC_URL
100134

@@ -110,11 +144,6 @@ const Home = () => {
110144
return
111145
}
112146

113-
setAppName(({ input }) => ({
114-
input: '',
115-
diff: input || DEFAULT_APP_NAME,
116-
}))
117-
118147
setFromVersion(fromVersion)
119148
setToVersion(toVersion)
120149
setShouldShowDiff(true)
@@ -190,17 +219,31 @@ const Home = () => {
190219
</SettingsContainer>
191220
</HeaderContainer>
192221

193-
<Typography.Title level={5}>What's your app name?</Typography.Title>
222+
<AppDetailsContainer>
223+
<AppNameField>
224+
<Typography.Title level={5}>What's your app name?</Typography.Title>
194225

195-
<Input
196-
size="large"
197-
placeholder={DEFAULT_APP_NAME}
198-
value={appName.input}
199-
onChange={({ target }) =>
200-
setAppName(({ diff }) => ({ input: target.value, diff }))
201-
}
202-
/>
226+
<Input
227+
size="large"
228+
placeholder={DEFAULT_APP_NAME}
229+
value={appName}
230+
onChange={({ target }) => setAppName((value) => target.value)}
231+
/>
232+
</AppNameField>
233+
234+
<AppPackageField>
235+
<Typography.Title level={5}>
236+
What's your app package?
237+
</Typography.Title>
203238

239+
<Input
240+
size="large"
241+
placeholder={DEFAULT_APP_PACKAGE}
242+
value={appPackage}
243+
onChange={({ target }) => setAppPackage((value) => target.value)}
244+
/>
245+
</AppPackageField>
246+
</AppDetailsContainer>
204247
<VersionSelector
205248
key={packageName}
206249
showDiff={handleShowDiff}
@@ -210,11 +253,19 @@ const Home = () => {
210253
isPackageNameDefinedInURL={isPackageNameDefinedInURL}
211254
/>
212255
</Container>
256+
{/*
257+
Pass empty values for app name and package if they're the defaults to
258+
hint to diffing components they don't need to further patch the
259+
rn-diff-purge output.
260+
*/}
213261
<DiffViewer
214262
shouldShowDiff={shouldShowDiff}
215263
fromVersion={fromVersion}
216264
toVersion={toVersion}
217-
appName={appName.diff}
265+
appName={deferredAppName !== DEFAULT_APP_NAME ? deferredAppName : ''}
266+
appPackage={
267+
deferredAppPackage !== DEFAULT_APP_PACKAGE ? deferredAppPackage : ''
268+
}
218269
packageName={packageName}
219270
language={language}
220271
/>

src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const DEFAULT_APP_NAME = 'RnDiffApp'
2+
export const DEFAULT_APP_PACKAGE = 'com'
23

34
export const PACKAGE_NAMES = {
45
RN: 'react-native',

0 commit comments

Comments
 (0)