120 lines
4.3 KiB
Dart
120 lines
4.3 KiB
Dart
import 'dart:math';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'test_utils.dart';
|
|
|
|
/// URL 관련 유틸리티 기능을 제공하는 클래스
|
|
class UrlUtils {
|
|
/// 이벤트 공개 URL의 기본 도메인 (프로덕션)
|
|
static const String eventBaseUrl = 'https://lanebow.com/events/';
|
|
|
|
/// 공개 URL 해시 생성
|
|
///
|
|
/// 8자리 영숫자 해시를 생성합니다.
|
|
/// 보안 및 충돌 방지를 위해 충분한 길이와 랜덤성을 가집니다.
|
|
/// 테스트 환경에서는 예측 가능한 해시를 반환합니다.
|
|
static String generatePublicHash() {
|
|
// 테스트 환경에서는 예측 가능한 해시 반환
|
|
if (TestUtils.isInTest) {
|
|
return TestUtils.getTestHash();
|
|
}
|
|
|
|
// 일반 환경에서는 랜덤 해시 생성
|
|
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
final random = Random();
|
|
return String.fromCharCodes(
|
|
Iterable.generate(
|
|
8,
|
|
(_) => chars.codeUnitAt(random.nextInt(chars.length)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// 이벤트 공개 URL 생성
|
|
///
|
|
/// [hash] 값을 기반으로 완전한 이벤트 공개 URL을 생성합니다.
|
|
static String getEventPublicUrl(String hash) {
|
|
return '$eventBaseUrl$hash';
|
|
}
|
|
|
|
/// URL을 클립보드에 복사하고 스낵바로 알림
|
|
///
|
|
/// [context]는 스낵바를 표시할 BuildContext입니다.
|
|
/// [url]은 복사할 URL 문자열입니다.
|
|
/// [duration]은 스낵바 표시 시간입니다. 기본값은 2초입니다.
|
|
static void copyUrlToClipboard(BuildContext context, String url, {Duration? duration}) {
|
|
Clipboard.setData(ClipboardData(text: url));
|
|
|
|
// 테스트 환경에서 안전하게 스낵바 표시
|
|
if (TestUtils.isInTest) {
|
|
// 테스트 환경에서는 로그만 출력
|
|
debugPrint('클립보드에 URL 복사됨: $url');
|
|
return;
|
|
}
|
|
|
|
// 일반 환경에서는 스낵바 표시
|
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
if (context.mounted) {
|
|
final snackBar = SnackBar(
|
|
content: const Text('공개 URL이 클립보드에 복사되었습니다'),
|
|
action: SnackBarAction(
|
|
label: '확인',
|
|
onPressed: () {},
|
|
),
|
|
duration: duration ?? const Duration(seconds: 2),
|
|
);
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
});
|
|
}
|
|
|
|
/// 해시 생성/재생성 후 스낵바로 알림
|
|
///
|
|
/// [context]는 스낵바를 표시할 BuildContext입니다.
|
|
/// [isNew]는 새로 생성된 해시인지 여부입니다. true면 생성, false면 재생성 메시지를 표시합니다.
|
|
/// [hash]는 생성된 해시 값입니다.
|
|
///
|
|
/// 주의: 이 메서드는 더 이상 직접 사용하지 않습니다. 테스트 환경에서 문제가 발생할 수 있습니다.
|
|
/// 대신 각 화면에서 직접 스낵바를 표시하는 것이 좋습니다.
|
|
@Deprecated('테스트 환경에서 문제가 발생할 수 있습니다. 대신 각 화면에서 직접 스낵바를 표시하세요.')
|
|
static void showHashGenerationSnackbar(BuildContext context, bool isNew, String hash) {
|
|
final message = isNew
|
|
? '공개 URL 해시가 생성되었습니다'
|
|
: '공개 URL 해시가 재생성되었습니다. 이전 URL은 더 이상 유효하지 않습니다';
|
|
|
|
final url = getEventPublicUrl(hash);
|
|
|
|
// 테스트 환경에서는 항상 로그만 출력
|
|
if (TestUtils.isInTest) {
|
|
debugPrint('해시 생성 완료: $message, URL: $url');
|
|
return;
|
|
}
|
|
|
|
// 일반 환경에서는 스낵바 표시 (context가 유효한지 확인)
|
|
if (context.mounted) {
|
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
if (context.mounted) {
|
|
try {
|
|
final snackBar = SnackBar(
|
|
content: Text(message),
|
|
action: SnackBarAction(
|
|
label: 'URL 복사',
|
|
onPressed: () => copyUrlToClipboard(context, url),
|
|
),
|
|
duration: const Duration(seconds: 4),
|
|
);
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
} catch (e) {
|
|
debugPrint('스낵바 표시 오류: $e');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|