M1 공유 타겟(U1)+M2 저장 진행 알림: ACTION_SEND 인텐트 필터+ShareTarget/SharePayload(RED 7건)+루트 타이머 큐 전송(am start 인텐트 E2E로 서버 큐 반영 실증), 오프라인 저장 Android ProgressBar 노티(5% 스로틀)→폰 저장 완료 전환(34MB E2E, Report(1) 되덮어쓰기 방지). 154/154 GREEN
This commit is contained in:
parent
69094595a5
commit
04ff0ff93d
7 changed files with 166 additions and 6 deletions
|
|
@ -163,6 +163,21 @@ public sealed class QueuePage : ContentPage
|
|||
_summary.Text = err != null ? $"❌ {err}" : items.Count == 0 ? "대기 중인 항목이 없습니다" : $"{items.Count}건";
|
||||
}
|
||||
|
||||
/// <summary>U1: 공유받은 링크 처리 결과 표시(루트 타이머가 호출).</summary>
|
||||
public void ShowSharedResult(string message) => _summary.Text = message;
|
||||
|
||||
/// <summary>U1: 공유 타겟으로 받은 텍스트에서 URL 을 추출해 PC 대기열에 추가.</summary>
|
||||
private async Task HandleSharedUrlAsync()
|
||||
{
|
||||
var shared = ShareTarget.Consume();
|
||||
if (shared == null || !ApiClient.Instance.IsConfigured) return;
|
||||
var url = SharePayload.ExtractUrl(shared);
|
||||
if (url == null) { _summary.Text = "🔗 공유받은 텍스트에 URL 이 없습니다"; return; }
|
||||
_summary.Text = "🔗 공유 링크 전송 중…";
|
||||
var ok = await ApiClient.Instance.AddAsync(url);
|
||||
_summary.Text = ok ? $"🔗 공유 링크 전송됨: {url}" : "❌ 공유 링크 전송 실패";
|
||||
}
|
||||
|
||||
/// <summary>U5: 완료 로컬 알림(Android 13+ 는 최초 1회 권한 요청).</summary>
|
||||
private static async Task NotifyCompletionAsync(string title)
|
||||
{
|
||||
|
|
@ -234,14 +249,19 @@ public sealed class LibraryPage : ContentPage
|
|||
if (item == null) return;
|
||||
if (AppOfflineStore.Default.Exists(item.Id)) { button.Text = "✓ 저장됨"; return; }
|
||||
button.Text = "0%";
|
||||
var notifId = 5000 + Math.Abs(item.Id.GetHashCode() % 1000); // M2 진행 알림: 항목별 고정 id 로 갱신
|
||||
try
|
||||
{
|
||||
var dest = AppOfflineStore.Default.PathFor(item.Id);
|
||||
var progress = new Progress<double>(p => MainThread.BeginInvokeOnMainThread(
|
||||
() => button.Text = p >= 1 ? "✓ 저장됨" : $"{(int)(p * 100)}%"));
|
||||
var progress = new Progress<double>(p => MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
button.Text = p >= 1 ? "✓ 저장됨" : $"{(int)(p * 100)}%";
|
||||
if (p < 1) ShowSaveProgress(notifId, item.FileName, p); // 100% 는 완료 노티가 대체(되덮어쓰기 방지)
|
||||
}));
|
||||
await ApiClient.Instance.DownloadFileAsync(item, dest, progress, CancellationToken.None);
|
||||
AppOfflineStore.Default.Record(item.Id, item.FileName);
|
||||
button.Text = "✓ 저장됨";
|
||||
ShowSaveDone(notifId, item.FileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -249,6 +269,53 @@ public sealed class LibraryPage : ContentPage
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>M2: 오프라인 저장 진행 알림(같은 id 갱신) — 5% 단위 스로틀.</summary>
|
||||
private static int _lastNotifiedPercent = -1;
|
||||
|
||||
private static void ShowSaveProgress(int notifId, string fileName, double p)
|
||||
{
|
||||
var percent = (int)(p * 100);
|
||||
if (p < 1 && percent / 5 == _lastNotifiedPercent) return; // 알림 스팸 방지
|
||||
_lastNotifiedPercent = percent / 5;
|
||||
try
|
||||
{
|
||||
Plugin.LocalNotification.LocalNotificationCenter.Current.Show(new Plugin.LocalNotification.NotificationRequest
|
||||
{
|
||||
NotificationId = notifId,
|
||||
Title = "폰에 저장 중",
|
||||
Description = $"{fileName} — {percent}%",
|
||||
Android =
|
||||
{
|
||||
ChannelId = "vd_save",
|
||||
Ongoing = true,
|
||||
AutoCancel = false,
|
||||
ProgressBar = new Plugin.LocalNotification.AndroidOption.AndroidProgressBar
|
||||
{
|
||||
Max = 100,
|
||||
Progress = percent,
|
||||
IsIndeterminate = false,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static void ShowSaveDone(int notifId, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Plugin.LocalNotification.LocalNotificationCenter.Current.Show(new Plugin.LocalNotification.NotificationRequest
|
||||
{
|
||||
NotificationId = notifId,
|
||||
Title = "폰 저장 완료",
|
||||
Description = fileName,
|
||||
Android = { ChannelId = "vd_save", Ongoing = false, AutoCancel = true },
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private async void OpenPlayer(LibraryItem item)
|
||||
{
|
||||
// 탭 자식엔 NavigationPage 가 없어 PushAsync 불가 → 루트에서 모달 push (닫기는 상단바 뒤로)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue