Skip to content

Commit e58903a

Browse files
committed
support multiple versions
1 parent 41e1028 commit e58903a

File tree

3 files changed

+115
-83
lines changed

3 files changed

+115
-83
lines changed

src/client.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ export class Pushy {
9191
options = defaultClientOptions;
9292
clientType: 'Pushy' | 'Cresc' = 'Pushy';
9393
lastChecking?: number;
94-
lastRespJson?: Promise<any>;
94+
lastRespJson?: Promise<CheckResult>;
95+
lastRespText?: Promise<string>;
9596

9697
version = cInfo.rnu;
9798
loggerPromise = (() => {
@@ -294,19 +295,22 @@ export class Pushy {
294295
this.throwIfEnabled(new Error('errorChecking'));
295296
return this.lastRespJson ? await this.lastRespJson : emptyObj;
296297
}
297-
this.lastRespJson = resp.json();
298-
299-
const result: CheckResult = await this.lastRespJson;
300-
301-
log('checking result:', result);
302298

303299
if (resp.status !== 200) {
300+
const errorMessage = `${resp.status}: ${resp.statusText}`;
304301
this.report({
305302
type: 'errorChecking',
306-
message: result.message,
303+
message: errorMessage,
307304
});
308-
this.throwIfEnabled(new Error(result.message));
305+
this.throwIfEnabled(new Error(errorMessage));
306+
log('error checking response:', resp.status, await resp.text());
307+
return this.lastRespJson ? await this.lastRespJson : emptyObj;
309308
}
309+
this.lastRespJson = resp.json();
310+
311+
const result: CheckResult = await this.lastRespJson;
312+
313+
log('checking result:', result);
310314

311315
return result;
312316
};

src/provider.tsx

Lines changed: 79 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ import {
1414
} from 'react-native';
1515
import { Pushy, Cresc, sharedState } from './client';
1616
import { currentVersion, packageVersion, getCurrentVersionInfo } from './core';
17-
import { CheckResult, ProgressData, UpdateTestPayload } from './type';
17+
import {
18+
CheckResult,
19+
MixedCheckResult,
20+
ProgressData,
21+
UpdateTestPayload,
22+
} from './type';
1823
import { UpdateContext } from './context';
1924
import { URL } from 'react-native-url-polyfill';
2025
import { isInRollout } from './isInRollout';
@@ -158,84 +163,95 @@ export const UpdateProvider = ({
158163
return;
159164
}
160165
lastChecking.current = now;
161-
let info: CheckResult;
166+
let rootInfo: MixedCheckResult | undefined;
162167
try {
163-
info = await client.checkUpdate(extra);
168+
rootInfo = await client.checkUpdate(extra);
164169
} catch (e: any) {
165170
setLastError(e);
166171
alertError('更新检查失败', e.message);
167172
throwErrorIfEnabled(e);
168173
return;
169174
}
170-
if (!info) {
175+
if (!rootInfo) {
171176
return;
172177
}
173-
const rollout = info.config?.rollout?.[packageVersion];
174-
if (info.update && rollout) {
175-
if (!isInRollout(rollout)) {
176-
log(`not in ${rollout}% rollout, ignored`);
177-
return;
178-
}
179-
log(`in ${rollout}% rollout, continue`);
180-
}
181-
info.description = info.description ?? '';
182-
updateInfoRef.current = info;
183-
setUpdateInfo(info);
184-
if (info.expired) {
185-
if (
186-
options.onPackageExpired &&
187-
(await options.onPackageExpired(info)) === false
188-
) {
189-
log('onPackageExpired returned false, skipping');
190-
return;
178+
const versions = rootInfo.versions || [rootInfo as CheckResult];
179+
delete rootInfo.versions;
180+
for (const versionInfo of versions) {
181+
const info: CheckResult = {
182+
...versionInfo,
183+
...rootInfo,
184+
};
185+
const rollout = info.config?.rollout?.[packageVersion];
186+
if (info.update && rollout) {
187+
if (!isInRollout(rollout)) {
188+
log(`${info.name} not in ${rollout}% rollout, ignored`);
189+
continue;
190+
}
191+
log(`${info.name} in ${rollout}% rollout, continue`);
191192
}
192-
const { downloadUrl } = info;
193-
if (downloadUrl && sharedState.apkStatus === null) {
194-
if (options.updateStrategy === 'silentAndNow') {
195-
if (Platform.OS === 'android' && downloadUrl.endsWith('.apk')) {
196-
downloadAndInstallApk(downloadUrl);
197-
} else {
198-
Linking.openURL(downloadUrl);
193+
info.description = info.description ?? '';
194+
updateInfoRef.current = info;
195+
setUpdateInfo(info);
196+
if (info.expired) {
197+
if (
198+
options.onPackageExpired &&
199+
(await options.onPackageExpired(info)) === false
200+
) {
201+
log('onPackageExpired returned false, skipping');
202+
return;
203+
}
204+
const { downloadUrl } = info;
205+
if (downloadUrl && sharedState.apkStatus === null) {
206+
if (options.updateStrategy === 'silentAndNow') {
207+
if (Platform.OS === 'android' && downloadUrl.endsWith('.apk')) {
208+
downloadAndInstallApk(downloadUrl);
209+
} else {
210+
Linking.openURL(downloadUrl);
211+
}
212+
return info;
199213
}
214+
alertUpdate('提示', '您的应用版本已更新,点击更新下载安装新版本', [
215+
{
216+
text: '更新',
217+
onPress: () => {
218+
if (
219+
Platform.OS === 'android' &&
220+
downloadUrl.endsWith('.apk')
221+
) {
222+
downloadAndInstallApk(downloadUrl);
223+
} else {
224+
Linking.openURL(downloadUrl);
225+
}
226+
},
227+
},
228+
]);
229+
}
230+
} else if (info.update) {
231+
if (
232+
options.updateStrategy === 'silentAndNow' ||
233+
options.updateStrategy === 'silentAndLater'
234+
) {
235+
downloadUpdate(info);
200236
return info;
201237
}
202-
alertUpdate('提示', '您的应用版本已更新,点击更新下载安装新版本', [
203-
{
204-
text: '更新',
205-
onPress: () => {
206-
if (Platform.OS === 'android' && downloadUrl.endsWith('.apk')) {
207-
downloadAndInstallApk(downloadUrl);
208-
} else {
209-
Linking.openURL(downloadUrl);
210-
}
238+
alertUpdate(
239+
'提示',
240+
'检查到新的版本' + info.name + ',是否下载?\n' + info.description,
241+
[
242+
{ text: '取消', style: 'cancel' },
243+
{
244+
text: '确定',
245+
style: 'default',
246+
onPress: () => {
247+
downloadUpdate();
248+
},
211249
},
212-
},
213-
]);
214-
}
215-
} else if (info.update) {
216-
if (
217-
options.updateStrategy === 'silentAndNow' ||
218-
options.updateStrategy === 'silentAndLater'
219-
) {
220-
downloadUpdate(info);
221-
return info;
250+
],
251+
);
222252
}
223-
alertUpdate(
224-
'提示',
225-
'检查到新的版本' + info.name + ',是否下载?\n' + info.description,
226-
[
227-
{ text: '取消', style: 'cancel' },
228-
{
229-
text: '确定',
230-
style: 'default',
231-
onPress: () => {
232-
downloadUpdate();
233-
},
234-
},
235-
],
236-
);
253+
return info;
237254
}
238-
return info;
239255
},
240256
[
241257
client,

src/type.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
1-
export interface CheckResult {
2-
upToDate?: true;
3-
expired?: true;
4-
downloadUrl?: string;
5-
update?: true;
6-
name?: string; // version name
7-
hash?: string;
8-
description?: string;
9-
metaInfo?: string;
10-
config?: {
11-
rollout?: {
1+
export interface VersionInfo {
2+
name: string;
3+
hash: string;
4+
description: string;
5+
metaInfo: string;
6+
config: {
7+
rollout: {
128
[packageVersion: string]: number;
139
};
1410
[key: string]: any;
1511
};
1612
pdiff?: string;
1713
diff?: string;
1814
full?: string;
19-
paths?: string[];
15+
}
16+
17+
interface RootResult {
18+
upToDate?: true;
19+
expired?: true;
20+
downloadUrl?: string;
21+
update?: true;
2022
paused?: 'app' | 'package';
2123
message?: string;
24+
paths?: string[];
2225
}
2326

27+
export type CheckResult = RootResult & VersionInfo;
28+
29+
export type CheckResultV2 = RootResult & {
30+
versions?: VersionInfo[];
31+
};
32+
33+
export type MixedCheckResult = CheckResult | CheckResultV2;
34+
35+
2436
export interface ProgressData {
2537
hash: string;
2638
received: number;

0 commit comments

Comments
 (0)