desktop: Releases > Send for review (App Store submission state, builds by number, Submit / Resubmit / in-app purchases; Play versionCodes by number, Send to production, managed publishing, console plans for countries and Send changes for review), plan panel before every owner dialog with streamed progress; App info console steps for every console plan form with verify; Catalog price-change owner actions and the declined state; Data safety deletion answer; TestFlight create missing groups; Android SDK in Dependencies; upload progress in job toasts; boot check send-for-review cases on D1 and D3 state
This commit is contained in:
parent
33eb24a3dc
commit
2b101f0fd8
22 changed files with 1527 additions and 57 deletions
|
|
@ -2,7 +2,7 @@
|
|||
// into the app data folder in one click (checksum or signature verified, progress, cancel); the rest link out.
|
||||
// Store work needs none of them. Sources and licenses: docs/desktop.md.
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { api, type DownloadInfo, errorText, newJob, onDownload, type ToolStatus } from '../api';
|
||||
import { type AndroidSdkLookup, api, type DownloadInfo, errorText, type LocalTools, newJob, onDownload, type ToolStatus } from '../api';
|
||||
import { t } from '../i18n';
|
||||
import { bytes } from '../lib/format';
|
||||
import { shortPath } from '../paths';
|
||||
|
|
@ -23,6 +23,7 @@ interface Dl { job: string; stage: string; received: number; total: number | nul
|
|||
export function Dependencies() {
|
||||
const d = useData();
|
||||
const [tools, setTools] = useState<ToolStatus[] | null>(d.sidecar?.tools?.tools ?? null);
|
||||
const [sdk, setSdk] = useState<AndroidSdkLookup | null>(d.sidecar?.tools?.androidSdk ?? null);
|
||||
const [info, setInfo] = useState<DownloadInfo[]>([]);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
|
@ -31,8 +32,8 @@ export function Dependencies() {
|
|||
const refresh = useCallback(async () => {
|
||||
setBusy(true); setError(null);
|
||||
try {
|
||||
const [s, i] = await Promise.all([api.call<{ tools: ToolStatus[] }>('system.tools'), api.toolsInfo()]);
|
||||
setTools(s.tools); setInfo(i);
|
||||
const [s, i] = await Promise.all([api.call<LocalTools>('system.tools'), api.toolsInfo()]);
|
||||
setTools(s.tools); setInfo(i); setSdk(s.androidSdk ?? null);
|
||||
} catch (e) { setError(errorText(e)); } finally { setBusy(false); }
|
||||
}, []);
|
||||
useEffect(() => { refresh(); }, [refresh]);
|
||||
|
|
@ -113,6 +114,22 @@ export function Dependencies() {
|
|||
</div>
|
||||
)}
|
||||
</Card>
|
||||
{sdk && (
|
||||
<Card title={t('deps.sdkTitle')} icon="phone" sub={t('deps.sdkSub')} id="android-sdk"
|
||||
actions={sdk.path ? <Chip tone="ok">{t('deps.installed')}</Chip> : <><Chip tone="warn">{t('deps.missing')}</Chip><button className="btn btn-sm" onClick={() => open('https://developer.android.com/studio')}><Icon name="external" />{t('deps.getIt')}</button></>}>
|
||||
{sdk.path ? (
|
||||
<dl className="kv">
|
||||
<dt>{t('deps.sdkPath')}</dt><dd className="mono-id selectable" title={sdk.path}>{shortPath(sdk.path, d.info?.home)}</dd>
|
||||
<dt>{t('deps.sdkFrom')}</dt><dd className="small">{sdk.source}</dd>
|
||||
</dl>
|
||||
) : (
|
||||
<div className="stack" style={{ gap: 6 }}>
|
||||
<span className="small">{t('deps.sdkNone')}</span>
|
||||
<ul className="note-list small">{sdk.checked.map((c, i) => <li key={i} className="selectable">{d.info?.home ? c.split(d.info.home).join("~") : c}</li>)}</ul>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
)}
|
||||
<div className="grid g2">
|
||||
{info.map(m => (
|
||||
<Card key={m.tool} title={m.tool === 'chrome' ? 'Chrome for Testing' : `ffmpeg ${m.version ?? ''}`} icon={m.tool === 'chrome' ? 'globe' : 'image'} sub={m.installed ? t('deps.inAppData', { folder: m.folder }) : t('deps.notDownloaded')}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue