79 lines
2.7 KiB
Dart
79 lines
2.7 KiB
Dart
/// 대화 글자에 붙이는 업무 표시. 새 봉투 형식 없이 보통 대화로 오가고, 받는 쪽이 읽어서 업무 목록에 넣는다.
|
|
///
|
|
/// 📌 업무 [김민수] 결제 API 정리 (마감 10/30)
|
|
/// 🚨 긴급 호출: 서버가 멈췄어요
|
|
sealed class WorkNote {
|
|
const WorkNote();
|
|
|
|
/// 대화 글자로.
|
|
String encode();
|
|
|
|
/// 대화 글자에서 읽는다. 표시가 없으면 null. [now] 는 마감 연도를 정할 때 쓴다.
|
|
static WorkNote? parse(String body, {DateTime? now}) {
|
|
final t = body.trim();
|
|
if (t.startsWith(UrgentNote.prefix)) {
|
|
final text = t.substring(UrgentNote.prefix.length).trim();
|
|
return UrgentNote(text);
|
|
}
|
|
if (t.startsWith(TaskNote.prefix)) return TaskNote._parse(t.substring(TaskNote.prefix.length).trim(), now: now);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// 긴급 호출.
|
|
class UrgentNote extends WorkNote {
|
|
const UrgentNote(this.text);
|
|
static const prefix = '🚨 긴급 호출:';
|
|
final String text;
|
|
|
|
@override
|
|
String encode() => text.isEmpty ? prefix : '$prefix $text';
|
|
}
|
|
|
|
/// 업무 맡기기. [assignee] 는 이름(받는 쪽 기기에서 사람을 찾는 데 쓴다), [due] 는 마감 날짜.
|
|
class TaskNote extends WorkNote {
|
|
const TaskNote(this.title, {this.assignee, this.due});
|
|
static const prefix = '📌 업무';
|
|
final String title;
|
|
final String? assignee;
|
|
final DateTime? due;
|
|
|
|
@override
|
|
String encode() {
|
|
final b = StringBuffer(prefix);
|
|
if (assignee != null && assignee!.trim().isNotEmpty) b.write(' [${assignee!.trim().replaceAll(']', '')}]');
|
|
b.write(' ${title.trim()}');
|
|
if (due != null) b.write(' (마감 ${due!.month}/${due!.day})');
|
|
return b.toString();
|
|
}
|
|
|
|
static final _who = RegExp(r'^\[([^\]]*)\]\s*');
|
|
static final _due = RegExp(r'\s*\(마감 (\d{1,2})/(\d{1,2})\)\s*$');
|
|
|
|
static TaskNote? _parse(String rest, {DateTime? now}) {
|
|
var s = rest;
|
|
String? who;
|
|
final w = _who.firstMatch(s);
|
|
if (w != null) {
|
|
who = w.group(1)!.trim();
|
|
s = s.substring(w.end);
|
|
}
|
|
DateTime? due;
|
|
final d = _due.firstMatch(s);
|
|
if (d != null) {
|
|
final m = int.parse(d.group(1)!), day = int.parse(d.group(2)!);
|
|
if (m >= 1 && m <= 12 && day >= 1 && day <= 31) due = dueFrom(m, day, now ?? DateTime.now());
|
|
s = s.substring(0, d.start);
|
|
}
|
|
s = s.trim();
|
|
if (s.isEmpty) return null;
|
|
return TaskNote(s, assignee: who == null || who.isEmpty ? null : who, due: due);
|
|
}
|
|
|
|
/// "10/30" 은 [now] 기준 가장 가까운 앞날 (지난 지 두 달이 넘었으면 내년).
|
|
static DateTime dueFrom(int month, int day, DateTime now) {
|
|
final thisYear = DateTime(now.year, month, day);
|
|
return now.difference(thisYear).inDays > 60 ? DateTime(now.year + 1, month, day) : thisYear;
|
|
}
|
|
}
|