mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-23 02:36:05 +00:00
fix(ios): prevent share overlay from reappearing after dismissal
Add in-progress flag with iOS-specific delayed clearing to prevent the native share sheet from immediately reappearing after dismissal. On iOS, dismissing the share sheet fires window focus events that can re-trigger the share method. The 500ms delay prevents this re-trigger while remaining imperceptible to users.
This commit is contained in:
parent
286e04834e
commit
5a9f52ee62
1 changed files with 59 additions and 37 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
} from '@angular/core';
|
||||
import { WorkContextType } from '../../features/work-context/work-context.model';
|
||||
import { T } from 'src/app/t.const';
|
||||
import { IS_IOS } from '../../util/is-ios';
|
||||
import { TODAY_TAG } from '../../features/tag/tag.const';
|
||||
import { DialogConfirmComponent } from '../../ui/dialog-confirm/dialog-confirm.component';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
|
|
@ -57,6 +58,7 @@ export class WorkContextMenuComponent implements OnInit {
|
|||
isForProject: boolean = true;
|
||||
base: string = 'project';
|
||||
shareSupport: ShareSupport = 'none';
|
||||
private _isShareInProgress = false;
|
||||
|
||||
// TODO: Skipped for migration because:
|
||||
// Accessor inputs cannot be migrated as they are too complex.
|
||||
|
|
@ -133,53 +135,73 @@ export class WorkContextMenuComponent implements OnInit {
|
|||
protected readonly INBOX_PROJECT = INBOX_PROJECT;
|
||||
|
||||
async shareTasksAsMarkdown(): Promise<void> {
|
||||
const { status, markdown, contextTitle } =
|
||||
await this._markdownService.getMarkdownForContext(
|
||||
this.contextId,
|
||||
this.isForProject,
|
||||
);
|
||||
|
||||
if (status === 'empty' || !markdown) {
|
||||
this._snackService.open(T.GLOBAL_SNACK.NO_TASKS_TO_COPY);
|
||||
// Guard against concurrent share operations
|
||||
if (this._isShareInProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shareResult = await this._shareService.shareText({
|
||||
title: contextTitle ?? 'Super Productivity',
|
||||
text: markdown,
|
||||
});
|
||||
this._isShareInProgress = true;
|
||||
|
||||
if (shareResult === 'shared') {
|
||||
if (this.shareSupport === 'none') {
|
||||
const support = await this._shareService.getShareSupport();
|
||||
this._setShareSupport(support);
|
||||
try {
|
||||
const { status, markdown, contextTitle } =
|
||||
await this._markdownService.getMarkdownForContext(
|
||||
this.contextId,
|
||||
this.isForProject,
|
||||
);
|
||||
|
||||
if (status === 'empty' || !markdown) {
|
||||
this._snackService.open(T.GLOBAL_SNACK.NO_TASKS_TO_COPY);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shareResult === 'cancelled') {
|
||||
return;
|
||||
}
|
||||
const shareResult = await this._shareService.shareText({
|
||||
title: contextTitle ?? 'Super Productivity',
|
||||
text: markdown,
|
||||
});
|
||||
|
||||
const didCopy = await this._markdownService.copyMarkdownText(markdown);
|
||||
if (didCopy) {
|
||||
if (shareResult === 'unavailable') {
|
||||
this._snackService.open(T.GLOBAL_SNACK.SHARE_UNAVAILABLE_FALLBACK);
|
||||
this._setShareSupport('none');
|
||||
} else if (shareResult === 'failed') {
|
||||
this._snackService.open(T.GLOBAL_SNACK.SHARE_FAILED_FALLBACK);
|
||||
this._setShareSupport('none');
|
||||
if (shareResult === 'shared') {
|
||||
if (this.shareSupport === 'none') {
|
||||
const support = await this._shareService.getShareSupport();
|
||||
this._setShareSupport(support);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shareResult === 'cancelled') {
|
||||
return;
|
||||
}
|
||||
|
||||
const didCopy = await this._markdownService.copyMarkdownText(markdown);
|
||||
if (didCopy) {
|
||||
if (shareResult === 'unavailable') {
|
||||
this._snackService.open(T.GLOBAL_SNACK.SHARE_UNAVAILABLE_FALLBACK);
|
||||
this._setShareSupport('none');
|
||||
} else if (shareResult === 'failed') {
|
||||
this._snackService.open(T.GLOBAL_SNACK.SHARE_FAILED_FALLBACK);
|
||||
this._setShareSupport('none');
|
||||
} else {
|
||||
this._snackService.open(T.GLOBAL_SNACK.COPY_TO_CLIPPBOARD);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._snackService.open({
|
||||
msg: T.GLOBAL_SNACK.SHARE_FAILED,
|
||||
type: 'ERROR',
|
||||
});
|
||||
this._setShareSupport('none');
|
||||
} finally {
|
||||
// iOS-specific: Delay clearing flag to prevent re-trigger from focus events
|
||||
// On iOS, dismissing the native share sheet fires window focus events
|
||||
// that can cause the method to be called again
|
||||
if (IS_IOS) {
|
||||
setTimeout(() => {
|
||||
this._isShareInProgress = false;
|
||||
}, 500);
|
||||
} else {
|
||||
this._snackService.open(T.GLOBAL_SNACK.COPY_TO_CLIPPBOARD);
|
||||
this._isShareInProgress = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._snackService.open({
|
||||
msg: T.GLOBAL_SNACK.SHARE_FAILED,
|
||||
type: 'ERROR',
|
||||
});
|
||||
this._setShareSupport('none');
|
||||
}
|
||||
|
||||
async unplanAllTodayTasks(): Promise<void> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue