Add folder-level revert action in Git changes tree (#1390)
* feat: add folder-level revert for git changes * Fix bot comments. Fix confirmation dialog for mobile view. * fix --------- Co-authored-by: Konstantin Zolin <zolin_ka@vk.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Konstantin Zolin
Bohdan Triapitsyn
parent
7b1b3167a4
commit
9b52222ef1
@@ -1711,16 +1711,23 @@ export const GitView: React.FC = () => {
|
||||
[currentDirectory, refreshStatusAndBranches, git, t]
|
||||
);
|
||||
|
||||
const handleRevertAll = React.useCallback(
|
||||
async (paths: string[]) => {
|
||||
if (!currentDirectory || paths.length === 0 || isRevertingAll) {
|
||||
const handleRevertPaths = React.useCallback(
|
||||
async (paths: string[], setGlobalReverting: boolean, scope: 'all' | 'working' = 'all') => {
|
||||
if (!currentDirectory || paths.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uniquePaths = Array.from(new Set(paths));
|
||||
if (isRevertingAll || uniquePaths.some((path) => revertingPaths.has(path))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stagedPaths = new Set(stagedChangeEntries.map((entry) => entry.path));
|
||||
const touchesStagedIndex = uniquePaths.some((path) => stagedPaths.has(path));
|
||||
setIsRevertingAll(true);
|
||||
const touchesStagedIndex = scope === 'all' && uniquePaths.some((path) => stagedPaths.has(path));
|
||||
|
||||
if (setGlobalReverting) {
|
||||
setIsRevertingAll(true);
|
||||
}
|
||||
setRevertingPaths((previous) => {
|
||||
const next = new Set(previous);
|
||||
uniquePaths.forEach((path) => next.add(path));
|
||||
@@ -1732,7 +1739,7 @@ export const GitView: React.FC = () => {
|
||||
try {
|
||||
await Promise.all(uniquePaths.map(async (filePath) => {
|
||||
try {
|
||||
await git.revertGitFile(currentDirectory, filePath);
|
||||
await git.revertGitFile(currentDirectory, filePath, { scope });
|
||||
} catch (err) {
|
||||
failed.push({
|
||||
path: filePath,
|
||||
@@ -1769,10 +1776,26 @@ export const GitView: React.FC = () => {
|
||||
uniquePaths.forEach((path) => next.delete(path));
|
||||
return next;
|
||||
});
|
||||
setIsRevertingAll(false);
|
||||
if (setGlobalReverting) {
|
||||
setIsRevertingAll(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
[bumpIndexRevision, currentDirectory, git, isRevertingAll, refreshStatusAndBranches, stagedChangeEntries, t]
|
||||
[bumpIndexRevision, currentDirectory, git, isRevertingAll, refreshStatusAndBranches, revertingPaths, stagedChangeEntries, t]
|
||||
);
|
||||
|
||||
const handleRevertAll = React.useCallback(
|
||||
async (paths: string[]) => {
|
||||
await handleRevertPaths(paths, true);
|
||||
},
|
||||
[handleRevertPaths]
|
||||
);
|
||||
|
||||
const handleRevertDirectory = React.useCallback(
|
||||
async (paths: string[]) => {
|
||||
await handleRevertPaths(paths, false, 'working');
|
||||
},
|
||||
[handleRevertPaths]
|
||||
);
|
||||
|
||||
const handleViewChangeDiff = React.useCallback((path: string, staged: boolean) => {
|
||||
@@ -2405,6 +2428,7 @@ export const GitView: React.FC = () => {
|
||||
isRevertingAll={isRevertingAll}
|
||||
onVisiblePathsChange={setVisibleChangePaths}
|
||||
onRevertAll={handleRevertAll}
|
||||
onRevertDirectory={handleRevertDirectory}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ interface ChangesPanelProps {
|
||||
onVisiblePathsChange?: (paths: string[]) => void;
|
||||
/** Reverts every changed path across all groups; rendered once for the panel. */
|
||||
onRevertAll?: (paths: string[]) => Promise<void> | void;
|
||||
onRevertDirectory?: (paths: string[]) => Promise<void> | void;
|
||||
}
|
||||
|
||||
const CHANGE_LIST_VIRTUALIZE_THRESHOLD = 1000;
|
||||
@@ -67,6 +68,12 @@ type PanelRow =
|
||||
| { type: 'directory'; key: string; groupIndex: number; directory: ChangesTreeDirectoryNode; depth: number }
|
||||
| { type: 'revert-all'; key: string };
|
||||
|
||||
type PendingDirectoryRevert = {
|
||||
path: string;
|
||||
paths: string[];
|
||||
count: number;
|
||||
};
|
||||
|
||||
const expandedKey = (groupId: string, path: string): string => `${groupId} ${path}`;
|
||||
|
||||
export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
@@ -77,6 +84,7 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
headerBackgroundClassName = 'bg-sidebar',
|
||||
onVisiblePathsChange,
|
||||
onRevertAll,
|
||||
onRevertDirectory,
|
||||
}) => {
|
||||
const { t } = useI18n();
|
||||
const scrollRef = React.useRef<HTMLDivElement | null>(null);
|
||||
@@ -88,6 +96,7 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
const [collapsedGroups, setCollapsedGroups] = React.useState<Set<string>>(new Set());
|
||||
const [expandedDirectories, setExpandedDirectories] = React.useState<Set<string>>(new Set());
|
||||
const [revertAllOpen, setRevertAllOpen] = React.useState(false);
|
||||
const [pendingDirectoryRevert, setPendingDirectoryRevert] = React.useState<PendingDirectoryRevert | null>(null);
|
||||
|
||||
const trees = React.useMemo(
|
||||
() => visibleGroups.map((group) => buildChangesTree(group.entries)),
|
||||
@@ -276,6 +285,9 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
return Array.from(seen);
|
||||
}, [visibleGroups]);
|
||||
const revertAllCount = allChangePaths.length;
|
||||
const isPendingDirectoryReverting = pendingDirectoryRevert
|
||||
? isRevertingAll || pendingDirectoryRevert.paths.some((path) => revertingPaths.has(path))
|
||||
: false;
|
||||
|
||||
const handleConfirmRevertAll = React.useCallback(async () => {
|
||||
if (!onRevertAll || isRevertingAll || allChangePaths.length === 0) {
|
||||
@@ -285,6 +297,14 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
setRevertAllOpen(false);
|
||||
}, [allChangePaths, isRevertingAll, onRevertAll]);
|
||||
|
||||
const handleConfirmRevertDirectory = React.useCallback(async () => {
|
||||
if (!onRevertDirectory || !pendingDirectoryRevert || isPendingDirectoryReverting) {
|
||||
return;
|
||||
}
|
||||
await onRevertDirectory(pendingDirectoryRevert.paths);
|
||||
setPendingDirectoryRevert(null);
|
||||
}, [isPendingDirectoryReverting, onRevertDirectory, pendingDirectoryRevert]);
|
||||
|
||||
const renderHeader = React.useCallback(
|
||||
(group: ChangesGroupConfig, isFirst: boolean) => {
|
||||
const collapsed = collapsedGroups.has(group.id);
|
||||
@@ -333,6 +353,8 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
const renderDirectory = React.useCallback(
|
||||
(group: ChangesGroupConfig, directory: ChangesTreeDirectoryNode, depth: number) => {
|
||||
const isExpanded = expandedDirectories.has(expandedKey(group.id, directory.path));
|
||||
const directoryPaths = directory.files.map((file) => file.path);
|
||||
const isDirectoryReverting = isRevertingAll || directoryPaths.some((path) => revertingPaths.has(path));
|
||||
return (
|
||||
<div
|
||||
className={cn('group flex items-center gap-2 py-1.5 hover:bg-sidebar/40', ROW_PADDING_CLASSNAME)}
|
||||
@@ -358,6 +380,22 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
</span>
|
||||
<span className="ml-auto shrink-0 typography-micro text-muted-foreground">{directory.files.length}</span>
|
||||
</button>
|
||||
{group.showRevertActions !== false && onRevertDirectory ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setPendingDirectoryRevert({ path: directory.path, paths: directoryPaths, count: directoryPaths.length })}
|
||||
disabled={isDirectoryReverting}
|
||||
className="flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50"
|
||||
aria-label={t('gitView.changes.revertDirectoryAria', { path: directory.path })}
|
||||
title={t('gitView.changes.revertDirectoryTooltip')}
|
||||
>
|
||||
{isDirectoryReverting ? (
|
||||
<Icon name="loader-4" className="size-3.5 animate-spin" />
|
||||
) : (
|
||||
<Icon name="arrow-go-back" className="size-3.5" />
|
||||
)}
|
||||
</button>
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => group.onActionAll(directory.files.map((file) => file.path))}
|
||||
@@ -376,7 +414,7 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
</div>
|
||||
);
|
||||
},
|
||||
[expandedDirectories, t, toggleDirectoryExpanded]
|
||||
[expandedDirectories, isRevertingAll, onRevertDirectory, revertingPaths, t, toggleDirectoryExpanded]
|
||||
);
|
||||
|
||||
const renderRow = React.useCallback(
|
||||
@@ -523,6 +561,39 @@ export const ChangesPanel: React.FC<ChangesPanelProps> = ({
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
open={!!pendingDirectoryRevert}
|
||||
onOpenChange={(open) => {
|
||||
if (!isPendingDirectoryReverting && !open) setPendingDirectoryRevert(null);
|
||||
}}
|
||||
>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('gitView.changes.revertDirectoryDialogTitle')}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{pendingDirectoryRevert
|
||||
? pendingDirectoryRevert.count === 1
|
||||
? t('gitView.changes.revertDirectoryDescriptionSingle', { count: pendingDirectoryRevert.count, path: pendingDirectoryRevert.path })
|
||||
: t('gitView.changes.revertDirectoryDescriptionPlural', { count: pendingDirectoryRevert.count, path: pendingDirectoryRevert.path })
|
||||
: null}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" size="sm" onClick={() => setPendingDirectoryRevert(null)} disabled={isPendingDirectoryReverting}>
|
||||
{t('gitView.common.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
onClick={() => void handleConfirmRevertDirectory()}
|
||||
disabled={isPendingDirectoryReverting || !pendingDirectoryRevert}
|
||||
>
|
||||
{isPendingDirectoryReverting ? t('gitView.changes.reverting') : t('gitView.changes.revertDirectory')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -546,24 +546,30 @@ export const dict = {
|
||||
'gitView.branch.updateTitle': 'Update branch',
|
||||
'gitView.changes.changedFilesAria': 'Changed files',
|
||||
'gitView.changes.clearSelectionAria': 'Clear file selection',
|
||||
'gitView.changes.collapseDirectoryAria': 'Collapse Directory aria label',
|
||||
'gitView.changes.expandDirectoryAria': 'Expand Directory aria label',
|
||||
'gitView.changes.collapseDirectoryAria': 'Collapse directory {path}',
|
||||
'gitView.changes.expandDirectoryAria': 'Expand directory {path}',
|
||||
'gitView.changes.revertAll': 'Revert all',
|
||||
'gitView.changes.revertAllDescriptionPlural': 'Revert {count} changed files? This cannot be undone.',
|
||||
'gitView.changes.revertAllDescriptionSingle': 'Revert {count} changed file? This cannot be undone.',
|
||||
'gitView.changes.revertAllDialogTitle': 'Revert all changes?',
|
||||
'gitView.changes.revertFileAria': 'Revert File aria label',
|
||||
'gitView.changes.revertDirectoryAria': 'Revert changes in {path}',
|
||||
'gitView.changes.revertDirectory': 'Revert folder',
|
||||
'gitView.changes.revertDirectoryDescriptionPlural': 'This will discard local changes in {count} files under {path}.',
|
||||
'gitView.changes.revertDirectoryDescriptionSingle': 'This will discard local changes in {count} file under {path}.',
|
||||
'gitView.changes.revertDirectoryDialogTitle': 'Revert folder changes?',
|
||||
'gitView.changes.revertDirectoryTooltip': 'Revert folder changes',
|
||||
'gitView.changes.revertFileAria': 'Revert changes in {path}',
|
||||
'gitView.changes.revertFileTooltip': 'Revert changes',
|
||||
'gitView.changes.reverting': 'Reverting...',
|
||||
'gitView.changes.selectAllAria': 'Select all files',
|
||||
'gitView.changes.selectFileAria': 'Select File aria label',
|
||||
'gitView.changes.selectFileAria': 'Select {path}',
|
||||
'gitView.changes.stagedTitle': 'Staged',
|
||||
'gitView.changes.resizeSplitAria': 'Resize staged and unstaged changes',
|
||||
'gitView.changes.stageAllAria': 'Stage all changes',
|
||||
'gitView.changes.stageDirectoryAria': 'Stage all changes in {path}',
|
||||
'gitView.changes.stageFileAria': 'Stage {path}',
|
||||
'gitView.changes.title': 'Changes',
|
||||
'gitView.changes.toggleDirectorySelectionAria': 'Toggle Directory Selection aria label',
|
||||
'gitView.changes.toggleDirectorySelectionAria': 'Toggle selection for {path}',
|
||||
'gitView.changes.unstageAllAria': 'Unstage all changes',
|
||||
'gitView.changes.unstageDirectoryAria': 'Unstage all changes in {path}',
|
||||
'gitView.changes.unstageFileAria': 'Unstage {path}',
|
||||
|
||||
@@ -553,6 +553,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
"gitView.changes.revertAllDescriptionPlural": "Se descartarán los cambios locales de todos los archivos de la lista.",
|
||||
"gitView.changes.revertAllDescriptionSingle": "Se descartarán los cambios locales del archivo seleccionado.",
|
||||
"gitView.changes.revertAllDialogTitle": "¿Revertir todos los cambios?",
|
||||
"gitView.changes.revertDirectoryAria": "Revertir cambios en {path}",
|
||||
"gitView.changes.revertDirectory": "Revertir carpeta",
|
||||
"gitView.changes.revertDirectoryDescriptionPlural": "Se descartarán los cambios locales de {count} archivos en {path}.",
|
||||
"gitView.changes.revertDirectoryDescriptionSingle": "Se descartarán los cambios locales de {count} archivo en {path}.",
|
||||
"gitView.changes.revertDirectoryDialogTitle": "¿Revertir cambios de la carpeta?",
|
||||
"gitView.changes.revertDirectoryTooltip": "Revertir cambios de la carpeta",
|
||||
"gitView.changes.revertFileAria": "Revertir archivo",
|
||||
"gitView.changes.revertFileTooltip": "Revertir cambios",
|
||||
"gitView.changes.reverting": "Revertiendo...",
|
||||
|
||||
@@ -553,6 +553,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.changes.revertAllDescriptionPlural': '선택한 파일 {count}개의 변경 사항을 되돌립니다.',
|
||||
'gitView.changes.revertAllDescriptionSingle': '선택한 파일 {count}개의 변경 사항을 되돌립니다.',
|
||||
'gitView.changes.revertAllDialogTitle': '모든 변경 사항을 되돌릴까요?',
|
||||
'gitView.changes.revertDirectoryAria': '{path} 디렉터리의 변경 사항 되돌리기',
|
||||
'gitView.changes.revertDirectory': '폴더 되돌리기',
|
||||
'gitView.changes.revertDirectoryDescriptionPlural': '{path} 아래 파일 {count}개의 로컬 변경 사항을 버립니다.',
|
||||
'gitView.changes.revertDirectoryDescriptionSingle': '{path} 아래 파일 {count}개의 로컬 변경 사항을 버립니다.',
|
||||
'gitView.changes.revertDirectoryDialogTitle': '폴더 변경 사항을 되돌릴까요?',
|
||||
'gitView.changes.revertDirectoryTooltip': '폴더 변경 사항 되돌리기',
|
||||
'gitView.changes.revertFileAria': '파일 변경 사항 되돌리기',
|
||||
'gitView.changes.revertFileTooltip': '변경 사항 되돌리기',
|
||||
'gitView.changes.reverting': '되돌리는 중…',
|
||||
|
||||
@@ -1583,6 +1583,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.changes.revertAllDescriptionPlural': 'Zmiany we wszystkich plikach z listy zostaną odrzucone.',
|
||||
'gitView.changes.revertAllDescriptionSingle': 'Zmiany w wybranym pliku zostaną odrzucone.',
|
||||
'gitView.changes.revertAllDialogTitle': 'Cofnąć wszystkie zmiany?',
|
||||
'gitView.changes.revertDirectoryAria': 'Cofnij zmiany w katalogu {path}',
|
||||
'gitView.changes.revertDirectory': 'Cofnij folder',
|
||||
'gitView.changes.revertDirectoryDescriptionPlural': 'Zmiany lokalne w {count} plikach w katalogu {path} zostaną odrzucone.',
|
||||
'gitView.changes.revertDirectoryDescriptionSingle': 'Zmiany lokalne w {count} pliku w katalogu {path} zostaną odrzucone.',
|
||||
'gitView.changes.revertDirectoryDialogTitle': 'Cofnąć zmiany w folderze?',
|
||||
'gitView.changes.revertDirectoryTooltip': 'Cofnij zmiany w folderze',
|
||||
'gitView.changes.revertFileAria': 'Cofnij plik',
|
||||
'gitView.changes.revertFileTooltip': 'Cofnij zmiany',
|
||||
'gitView.changes.reverting': 'Cofanie...',
|
||||
|
||||
@@ -553,6 +553,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
"gitView.changes.revertAllDescriptionPlural": "As alterações locais de todos os arquivos da lista serão descartadas.",
|
||||
"gitView.changes.revertAllDescriptionSingle": "As alterações locais do arquivo selecionado serão descartadas.",
|
||||
"gitView.changes.revertAllDialogTitle": "Reverter todas as alterações?",
|
||||
"gitView.changes.revertDirectoryAria": "Reverter alterações em {path}",
|
||||
"gitView.changes.revertDirectory": "Reverter pasta",
|
||||
"gitView.changes.revertDirectoryDescriptionPlural": "As alterações locais em {count} arquivos dentro de {path} serão descartadas.",
|
||||
"gitView.changes.revertDirectoryDescriptionSingle": "As alterações locais em {count} arquivo dentro de {path} serão descartadas.",
|
||||
"gitView.changes.revertDirectoryDialogTitle": "Reverter alterações da pasta?",
|
||||
"gitView.changes.revertDirectoryTooltip": "Reverter alterações da pasta",
|
||||
"gitView.changes.revertFileAria": "Revertir arquivo",
|
||||
"gitView.changes.revertFileTooltip": "Revertir alterações",
|
||||
"gitView.changes.reverting": "Revertiendo...",
|
||||
|
||||
@@ -553,6 +553,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
"gitView.changes.revertAllDescriptionPlural": "Скасувати зміни у вибраних файлах?",
|
||||
"gitView.changes.revertAllDescriptionSingle": "Скасувати зміни у вибраному файлі?",
|
||||
"gitView.changes.revertAllDialogTitle": "Скасувати всі зміни?",
|
||||
"gitView.changes.revertDirectoryAria": "Скасувати зміни в каталозі {path}",
|
||||
"gitView.changes.revertDirectory": "Скасувати папку",
|
||||
"gitView.changes.revertDirectoryDescriptionPlural": "Локальні зміни в {count} файлах у {path} буде відкинуто.",
|
||||
"gitView.changes.revertDirectoryDescriptionSingle": "Локальні зміни в {count} файлі у {path} буде відкинуто.",
|
||||
"gitView.changes.revertDirectoryDialogTitle": "Скасувати зміни в папці?",
|
||||
"gitView.changes.revertDirectoryTooltip": "Скасувати зміни в папці",
|
||||
"gitView.changes.revertFileAria": "Скасувати зміни у файлі",
|
||||
"gitView.changes.revertFileTooltip": "Скасувати зміни",
|
||||
"gitView.changes.reverting": "Скасування...",
|
||||
|
||||
@@ -553,6 +553,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.changes.revertAllDescriptionPlural': '这将丢弃列表中 {count} 个文件的本地更改。',
|
||||
'gitView.changes.revertAllDescriptionSingle': '这将丢弃列表中 {count} 个文件的本地更改。',
|
||||
'gitView.changes.revertAllDialogTitle': '还原所有更改?',
|
||||
'gitView.changes.revertDirectoryAria': '还原 {path} 中的更改',
|
||||
'gitView.changes.revertDirectory': '还原文件夹',
|
||||
'gitView.changes.revertDirectoryDescriptionPlural': '这将丢弃 {path} 下 {count} 个文件的本地更改。',
|
||||
'gitView.changes.revertDirectoryDescriptionSingle': '这将丢弃 {path} 下 {count} 个文件的本地更改。',
|
||||
'gitView.changes.revertDirectoryDialogTitle': '还原文件夹更改?',
|
||||
'gitView.changes.revertDirectoryTooltip': '还原文件夹更改',
|
||||
'gitView.changes.revertFileAria': '还原 {path} 的更改',
|
||||
'gitView.changes.revertFileTooltip': '还原更改',
|
||||
'gitView.changes.reverting': '正在还原...',
|
||||
|
||||
@@ -566,6 +566,12 @@ export const dict: Record<I18nKey, string> = {
|
||||
'gitView.changes.revertAllDescriptionPlural': '這將捨棄列表中 {count} 個檔案的本地變更。',
|
||||
'gitView.changes.revertAllDescriptionSingle': '這將捨棄列表中 {count} 個檔案的本地變更。',
|
||||
'gitView.changes.revertAllDialogTitle': '還原所有變更?',
|
||||
'gitView.changes.revertDirectoryAria': '還原 {path} 中的變更',
|
||||
'gitView.changes.revertDirectory': '還原資料夾',
|
||||
'gitView.changes.revertDirectoryDescriptionPlural': '這將捨棄 {path} 下 {count} 個檔案的本地變更。',
|
||||
'gitView.changes.revertDirectoryDescriptionSingle': '這將捨棄 {path} 下 {count} 個檔案的本地變更。',
|
||||
'gitView.changes.revertDirectoryDialogTitle': '還原資料夾變更?',
|
||||
'gitView.changes.revertDirectoryTooltip': '還原資料夾變更',
|
||||
'gitView.changes.revertFileAria': '還原 {path} 的變更',
|
||||
'gitView.changes.revertFileTooltip': '還原變更',
|
||||
'gitView.changes.reverting': '正在還原...',
|
||||
|
||||
@@ -385,6 +385,7 @@
|
||||
@media (display-mode: standalone) and (max-width: 768px) {
|
||||
.pwa-dialog-content {
|
||||
--pwa-dialog-padding: clamp(0.75rem, 3vw, 1.25rem);
|
||||
top: auto;
|
||||
/* Browsers that don't understand dvh ignore the second declaration and
|
||||
keep the vh-based fallback. Newer browsers use 100dvh so Android
|
||||
Chrome's collapsible URL bar doesn't push the dialog footer off-screen. */
|
||||
|
||||
Reference in New Issue
Block a user