From 2a35fe55322d5d8d2347ffe035719520b4c27c5e Mon Sep 17 00:00:00 2001 From: bvandeusen Date: Sat, 28 Feb 2026 23:15:06 -0500 Subject: [PATCH] Add search, offline queue, app icon, and UI polish - Collapsible search in notes and tasks: magnifying glass in AppBar expands to a text field inline; close button resets the filter - Offline capture queue: failed quick-captures (NetworkException) are persisted to SharedPreferences and retried automatically on next successful submit or app start; badge shows pending count - App icon: book-with-sparkle logo from FabledAssistant SVG rendered at all Android densities with adaptive icon (indigo #6366f1 bg) - Dark mode subtitle fix: use colorScheme.onSurfaceVariant for note preview and conversation timestamp text - Remove swipe-to-delete (accidental deletions); long-press remains - Chat: SSE streaming reliability, polling fallback, title patching - Settings: theme toggle (system/light/dark) persisted to prefs - Notes: delete button in edit screen; body preview in list - Tasks: fix delete dialog context; description search support Co-Authored-By: Claude Sonnet 4.6 --- .../drawable-hdpi/ic_launcher_foreground.png | Bin 0 -> 6376 bytes .../drawable-mdpi/ic_launcher_foreground.png | Bin 0 -> 3692 bytes .../drawable-xhdpi/ic_launcher_foreground.png | Bin 0 -> 7553 bytes .../ic_launcher_foreground.png | Bin 0 -> 11057 bytes .../ic_launcher_foreground.png | Bin 0 -> 15671 bytes .../res/mipmap-anydpi-v26/ic_launcher.xml | 9 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 5525 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 2929 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 5897 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 11257 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 12783 bytes android/app/src/main/res/values/colors.xml | 4 + assets/icon/app_icon.png | Bin 0 -> 41214 bytes assets/icon/app_icon_fg.png | Bin 0 -> 27268 bytes lib/app.dart | 202 ++++++++++++- lib/data/api/chat_api.dart | 34 ++- lib/data/api/quick_capture_api.dart | 49 ++++ lib/data/models/conversation.dart | 2 +- lib/data/repositories/chat_repository.dart | 2 +- lib/providers/api_client_provider.dart | 5 + lib/providers/capture_queue_provider.dart | 29 ++ lib/providers/chat_provider.dart | 109 ++++--- lib/providers/settings_provider.dart | 31 ++ lib/screens/chat/chat_screen.dart | 21 +- .../chat/conversations_list_screen.dart | 62 ++-- lib/screens/notes/note_edit_screen.dart | 30 ++ lib/screens/notes/notes_list_screen.dart | 88 +++++- .../quick_capture/quick_capture_screen.dart | 269 ++++++++---------- lib/screens/settings/settings_screen.dart | 28 ++ lib/screens/tasks/task_edit_screen.dart | 7 +- lib/screens/tasks/tasks_list_screen.dart | 71 ++++- pubspec.lock | 72 +++++ pubspec.yaml | 12 + 33 files changed, 854 insertions(+), 282 deletions(-) create mode 100644 android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 android/app/src/main/res/values/colors.xml create mode 100644 assets/icon/app_icon.png create mode 100644 assets/icon/app_icon_fg.png create mode 100644 lib/data/api/quick_capture_api.dart create mode 100644 lib/providers/capture_queue_provider.dart diff --git a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..bcb2d8ffb70e770e579ab15f2b37b1a3c5a396ee GIT binary patch literal 6376 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 V9uRPie*A+0P*>IgS1VbC{}*u;OC|sS literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..f3bf7cb9357981e82b36b22dbffcef3ce4a961a6 GIT binary patch literal 3692 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 TtggJ8A_2NuhMLvtcCh~ddq^oz literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..7d83267cad9e622f81d207983b01aaa5eaf6551b GIT binary patch literal 7553 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 boF*dItaZfQGUg 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..c79c58a --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..843c7aaf95218ca05b555b6d34a7c9f82cc9b4f7 100644 GIT binary patch literal 5525 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 A?*IS* literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..da017d73be7b52874e135401e47fc94ee04fc8ad 100644 GIT binary patch literal 2929 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 literal 721 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD3?#3*wSy!iOI#yLg7ec#$`gxH85~pclTsBt za}(23gHjVyDhp4h+5i=O3-AeX1=1l$e`s#|#^}+&7(N@w0CIr{$Oe+Uk^K-ZP~83C zcc@hG6rikF&NPT(23>y!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..3103d3ed45a9f0922f85f625b836cfad7820c8df 100644 GIT binary patch literal 11257 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 QnYIw}(kfC75~gAQ27!Ngc>n+a literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 4d6372eebdb28e45604e46eeda8dd24651419bc0..9c663a5b47b80844d6f95052805cbbfe29a53544 100644 GIT binary patch literal 12783 zcmdtJRZv~Q_a=IP1QPt zlG1YeZscSlVC-n}o&h-6ICz-ZIGNel)!DcN*x3a**csW_1lZWzt{;y62L&6u?-r(R z|9gc`h2om;3UvS7gOi1g3Dn8R#{Pe=18y-41_0Q}b{lWCpdjPj@k0JssV>>C=pd!KCcv-g;V{@>bO=5o znMAM&o$n{|#J>QFUs{2%!O>1J#=&bNRtX8RB<0La%k=bIITbV1gTe1_$>CDh63Ij& zkEwx$eV+PCK(a3@G z?r1Xk45m@>aIcrgwA}Ssu2A$z%T6~(#{LZN>A>i-O?N4a9=s$BNS1){E8|=t+<=zNzM?zrS95S*34|$Td-}u>*_Q zQ6*j>X(X{{X96gwM!xIsa^9JiLd>d31#hp*VYu*|$DWyr76sTTYK+d4_oK3b;HHL| zk0We!zW)M12xP&#`~(78LS6e4V72)FrSS#t*u$Rq@EQ?J=WGAp8E71H1Kh+)Vh)( zPozq2MOdHcYqq{#Z8SY)FvoH3?ZN?vFqM_u9yhS|fMPHp61jl752bv9nFrV77mVM( zccZkRt^WXU!{`m@Ozp{bjl!!2l$S6MWzE-bIy&{FUbpy6{M;E&2ZxN?o>)+SBmx+eP|LRhkuAWg&b-ccc0?ALB8S9{WjxX!m790y_pF zsHio${9yL{D=ubuR#*ho@5=N*l|;E-5xyuhm56hAn1g5J@$ z1{-{LsXV-x#{BK*u_aeIBm?)zc(hKlEXn1l%xIc>!XGwR$Py>J)Vv2ZD>?X(V-ykq&Qa!JA%C@VnL4l2W`=xFT^}cKg~v z@w=(_e_RNnw?^P_X~ye+((T_qq%&ov&^6kw<=qxTr`)p2W#XtrES8c%*xbHEezfPp zyiW+KdQqbuBNAaHBU_^Iiib;TDbFekA$f0QOilSvLfkh~4^&Q%$QvQUzu66ukmmG= zmm+Brn=sWcAzz|mm)B0BS^r&vZbR^p)>8$cmS&`dQB6k8*FpdUqW{*oSjcPAc{@a5 zf#Ehmw)9r6txosFb7{~^t=c{P2Q$0gLHvjQ5^rVn(#f~KFV5N zY}Hy7uzAMhE`4%x_ffYr^2&mhKp>-PEbqT63B*|uYEyPt`-+RPofQUkzInPm#A@@i z;gQ#~i{W52tEyY2E6h>2cKwe{;Vn(NbF!36#>v>Hq&?#2s*l98c6>fZWQzKj^uGVH z$N1>=o_{wm4LFiyauOtSn&rJYpPf1XtN*|=REgfG zqdz`c-aO~K!4&#gc|F*L&zo%#Nraki><+&vsR|?n+AWY&0Km=G=&q^Mg{j&F1))5W6tN zz`qEt8Lv3XVHyE3Kjsd^-_uu%*Xa{TJ`TN^r(NE!Jz!nLxEOFh|*(-CWD`W8aQf#(Ih*RhToDY&n!qslx;(m;_o=g7 zK?U9NGH_D!zN0@%Idvk2C=IwNVJ$h$ z^I(?)xGR)Mu;(>Hxn!RWpoqe@fM+bMzb?;Q{_;vA^R3-)PEdh&9{Hu*eF4j;&>C>W z?BK?$TMBw)>Tx2Wo$;0pc!dH>c*nXQ8QeU-U*rjKQ6tD-Q9qNZU2wmi59%m)GxsBS zOP1rqWE76rW+V}uE0%fVUD+eOY5r&0pgxtp+z~n}(e^2_M=D8BZe89S=#r{#bJQsw z=NtPS0O~X5>b0~lWMTYd~ zTRx?BKpf-t+wU=vYhKqwi)Kn#^q4Kz(-&$eP@#vRlPV#XMt@^T=Z~u`J!h+#1>4KN z-NnnXq7;lCX)m%_6u%eGbcz655;7>w@jbdlsjVbu2g^Y!Toen0Eracz;P&8DX&(nF z?#J6tl|nmxr5t@S0}FNrIHG)x`O`dvUd}y~$mOeVlSk!wSYx#h$?n--dYXgE^-6U_ zcDH*72^FlTX~V=Pt#&C=$u{DAw5x)C!R}|whq&=s=s7E5r(VB2201kVy8|7%&9gLd0t+%_Laq9kj8o}o67l*$Ia=04nAqW4(zG>VcBiIjnPc>vBH=;2a}7LQ^3ilx}03 z&=`8ArP>x&y1nA6=p0_2V9MSXC`-BUt<8`1yY>Q&1sdnQ34Qd=*2kRLk_ap+v<*dV z!qX1p{|VK_YyJcl;%h z`#UE;J?Fy}=QCn8yfqc+l&@NR=JV)lcOIvHwdMg%1|{5T$L}nH zkK-{$(Y^*96>sME@}Nt`BK6c`GhWj_Y70e>Rp*f0dVrmZLygVPLthZeJ#`DaPOB>` zXCCz{XuS>08IJc+I>z+Onc-ii)}m+Vd|SfP-ARq6*5+2Z%MRyihNMx2b&$|^e&lNm z(G~NKuW~N#4_$LZPy<8ldeo66%D|%NzWI#a{54&2R}-FTY(CD)K2Ns}Z*HJ04BO{N za)EIB9tnBz(vt_Vqu4AhF{vnfGIWg0hY=i8wgF$&iQZ~}3 zV*JM{GnoZeiuOYE1I3cQ)oIjju%sm5tjo)qrk-CoQUXwws?czE6eBpa#*t46{NpXi zbUQvG*_h}RRA5GETu5}IvsJfowoT%EyH(^S+0M^a>z;6qq}pGlaS5fuX?Xg!nLH1P zN0%k|0|@WN=#kHrRMC65vN;Ib^yp!b{@FuX_F(ie&v5@`NGLR-(1-TxhiE^RK8&UEolzIiUKr-|AYKBScp zVpAhh5!{tZV$KPLV_>Tkg9uh>kK%AILRN}aD*Vp%KE*L4g~cNG!?kj)MxXl#6yma6 z&RvP)l9&>zzKw8BAcWwFU$<7+pPL}A)oEF=a7?pU{ksKyRa|t~?8kVLSA<##w}H5q z`ggl-VoVpARUVhV-~d_lj4k1k9;}IvGHhRKu#Z5L4#2apM+j*iL=Yz=JBz#z;^5?@ zciR;l8R=1bzTf!bJYrK@Gk+^&GwQ^2C-G|0pDRy{$SP8m*O9s)ulG7y{kf7WSAFvX z7Z5X?C!JFpjqZ&VlC7$X{KXPe6y~TBVRcP)Ikx8;zax?N>*QrDq0fM~v3LM%K4qLh zViV+xY4uLxE=81>@!^_V39RgVc&F>g!_U@;HhJB|$4INB*#Y*hg3>7a#Hpw)Tp}?d z$8NNIhYzRz(HnFoZRY|?$=nz(tUT!9hWF>#lkzkdwrX5w{YOJkZBheWlD?%2y7%#9 z`^k+9Y4<6&mg!eS%&HOZ{ZtFyQqSVWGv7b?3%a^QMPoq+920xkHrH;w>h=fr-w^`4 z6^F&cZo+3v-Xd2EjixK&5>{vDI;ASOA@&*3UNGR)sceYQZRj!NGfnVHAGhkFmeo86 z&fz^K%OEwCYQOL!ZbT$_R@qiD7o@% z654<%U?V!$+wf`-T9STk5?8l9M&hwD7=_H6V4;un-1XtBqkBXgXN6oej!LcfUh1fU zGLQ<{kK`YiGaMj3sgl`XR}RnV=;)H4mpciNd{wn_=11DImd5_$xhr1)hK$GSPhVau_Duvl)3rtV##UR_5AkZe6(-j&u z#x1wYo0G+~x%MK>ks`zC%g2}Ots=^_xE1QW%!QLhh#1nndovEJ zfF3&1KFgm-embT(aD1%Kqv0;?m134ONVoCqx2#_{@b%u=gau4P{co+}WYTd5U&LRo z1Zh=@LV8od)2{8_Gu+ps8vuln!93u9| zie-B#DUUa$S))Ji>}Ko8GD|K)&eA%ta`EjL&(>G&(Y-OAMuP9SMK9UV==xJg*$qi) zU`;>!D&3#t)Wf9?6XcsMqU2uutZz#goyT*A8)K8@#Y3lS^wGU>2y46>Alywage3ms zyw>Jf7fZKlWjy;-iJ$~N)%TyE9te(NYsL~We1Vt_M(BP!=km5f-5U2rx>1N1bE}SY z=52l=Yg!$?5zVfSq{6GnP;m5-fhS|NzJ!^PvCQ7R(`EH4vc2MSQ$Nphwq*n-r4MSPj5F3sy z=v&-U(T{tZ18frkR!W~7r7gFdvl%S|@z{7IA$j+&-k}j4W9AXCtJ0dx%WQTxlUQ*u zXZ2PHEl=mGZhakU59*%GXqugW?Oc@hv{jxvTjjO^cj@uX#p0eHoU;%kMV}`{zIgET z%og&Lxs_M^X2ftnUXd!mOP!|OK*X9D3YJjhNf33pyX@=vzP0OoWds~cGcLx=W?;Sn z|6%UT+sCabmL^GBsqDG$x+%L&b3pO}8L%IvE7EKT5S7{Q{qU+o8hsW}BUo^P98{%7szmwZ8J740-9sk<@*(c^<<=Vj-kA^R5s?>B)3-D8<)4MR8=W$>o2 zpOAc&7PC@jyfbrcQhN zr!eSR>6MEd_Nv!niy2gL=L(m-c``HCFP2GK=W0;<1UVi!e1X}%m_2yI!Rb9T4A+?) zBNr#$bom0?rLu}st_YE$WQP?WhvopgSi#4jFG=$V;U zzb`{VRwaCJ8HB$vx;c4;!>8~C<;?qC$ofUrt!j5yCeBoS{1BgH^%OaB>8~bXYvmDf z7bN;Tv36XyCxYp;>*A&P$!*`3agW&L#V#9)^NRFrX=8j8+?V+W`hp@%@6S0;RgcD9E;giQO7?;Xd`%K7YQH|1CI3+h^NZo#9aNc9 zjX0No4~F!+Pq(vfU9oWPU97!vyKpy(@Spbx72-ZN`vLs)(2NRh)@fe8&XF89bT~Oloz;4EIdb>JMTy=w8nV>`dj$s6=u!6+J8Sef+V9K%oeA`ACx#HWRXNuq{y~+=&Fqsm;S)r~lXgyHb`} zTmI6wVFH!|s52$+f$~SmJP>aw3PrM+sSu)mfYg_wJhYVY-uB733|Srr6M{f z=G8jQQscN9wW)F8Rnj=`VzC<`)cMyVFr5f@7xwj##YE#B`k;zfS>a~a^mrRD&dAlS z?{40=BP_p+^zhGC&DmN_-mj7}dGc0t? ztDdE87KsWTx_8!Uv^ehGY}wRmo~Rw_8Q*rZw#DnF_tE@PrZ@SjT!`y+SkYA$IU19d zShvs!{>7J_manon)4?yM?sRHTf)!9ZHEOQ2ku%g{=sZb9miI z%6N9c5<7@gPK?!3-uaRHd5L;xken$Itfo`3Bkz*Su|(G#f1pLhtBP3l&G8#`2y>E; zMtZ+>W4T(4jcO>}-n>xbZ;XGlL)h`(tyS_EGAeE^znPGvGJDaTiDMlNqLLBmI}EmL zbqxvy?O0Akr(})(f8-IwvR$M&cL%zd3;;Y`HtPYe_*WWht(iuB@C4Xgq4-0 zFRBS06&0dj?dVRB8+mxH{GvuQH zz4RJu^Y%9%Wd+G7^yBndE(kOXfgINb0#PjQ=eIv=CV z)MO8v^oECpj&u>H;%d;*gkq^^y5<|C((+eIDshbPO<2av#r)sMZ$VX5Zod|Po@|BP z2i@Z&wCLKerI~QX0z>vH2Z&AmqedrUt3rA18P1sd3_x_M0s-+^5S4_Y7WSzE$M z&zAM>!Lhf4#0&OZ5@t?Mc29fdtv)vj+K zs{qHWKLz9%uiYNrCEuF>ml{uI@qYKw=Z9Ht-65 zD4lTM9lm>RxG+k)e?Ky7eLf;<-e{HV!s@DViq9;v?Frd8%At?g-sDzGXv38MUNRU(zq+-+rm%H2Na7oEc4R`WIr3@Lb@FF zuNgh~JAsF6c6O~PFuf!BVIFTh%Pu3OC#4pnT|ne>Z}#UmeW$r~JhItf<;t}gMGsv5 zn#9qcS$TEcZW>r$v=coCT&EUyE532)1Kf&VNU_uDmHSPq(^c_uS27f?4gess$xR9o zMh1%6nPF}i;TnNa@vMfUoTJYZquf)C2sgC}I)3H{gPWF=i@zfx6HlcPhNXkfxdaBS zE_CqR_Zw?qx~BH&tat=cnwBFX%_2_RDKD@sJARgFNJRzhb=PTf5c=*m40s}pjTSW$ z=G=E$N0&wWBxaaZ@3dJ;)k(2rrFHA|u8^&)+eTO2oWj%d$eQ}A9~8wyLs6U-inug?8XzCt>i!+btUucYky6BhYLVwY1l$=?!ezyrQZv8Z+V*v+Z zwrPIyP+r=e_k&#&vq>}Gv^=q9wdC6qbV2l)gJ;%o>Lpt4QcGhawCIRypRH&zqOx^6 zQ;k}Sfbycnv7?INVtqKL;3|cn5g z2ahkC88BF!atbF%iuXgJ)T%vxryLw9A_N!`HpNc1?zDPP3e3(&BQ zZ_v~bk>+DIZAr@gkOt@ie|(Z=R~LhWcEX$5%o7`)HoN`c$WQmso#vz*?_a@7y8VZ_ zU}zHH##Irh6VuB8w6rBssS^K@kzJCDV}_d`Z;2O4PdLKA zi!ayOek9WZv4PGr{ATfOnekSZ;+=01?PT4>0i4`xpP5-sjH&zW;%M|6j85|C7)?ej+%Si(->95|(b|z3B5x z8bpO9c9#VNl2Q-=W8Md-_o4-;r#(s<^u_MIP39mF0dS(|PJxnQm38VPdPJ}+CBH-?nTA7o1wmGS;{SAjs>_`%|I#Cg(df^W%0q_FL zTfAtthaVj~ZH2h8_uJFq^jw5~WRlvq$`znxQjd23YJNk{_HDdjSGLNB zJkq>5O}i)VU!;gjU-a$r-z-G$rs~(DU9GP2%t!qtA#W`&nu ze}#}*W?q#)+10oa(c=2vuBNVYb(uri9{qNetPSI2MDQsj58U3msLIDex1mEJ>ALbgx*|FE|HUoN=+uLw2n zKO;Gab8+9UBTXoMy1;Lfuwp|0+B3x$$l7bA6_l+NparlxYZ(j_13a)HcA5_?X44#n z*{Q;<%!AZTGpbXq(Y+1H&BvrG=xTykJ(<0dECx^o$?}3}D~XtYbs%1}$YPKhrR@J4 zf#4W)sWM@a8gnacG3x~oe|BkI^eV4!F%K|o>5tTGU~WWp-&b@0(X6^;e+4{WmveewLI7eWd6N+u0jzl#E@{Jy z0-!9D+1G1#%x&UzE^1ET%0Ujm$u`{*0%g87TF}C>3S=)KS2ohs=4LUbXB@t(&TS!# zGJJZ7niSaWH;8%U?9;rcJ*HWrvoTz_|47fv$dnMTQ*A1wa@uWGU6+>1o{ahW<`fj7 zApNn1d-Db#l4P{s%KPIVx%60wD7DafYeFIL}erD7fwI?=9jP1r`3RxQ>&m2l(mV>fo88FwA+v2_7# z9iE}q}VU(HIOpa zlN1IRS4@;l*?_crlIzP+*^~BR$#zFC({&A^dM3D5WY9SD;<0oiaIzRb7^-7pU&KA6 zJ`Lz*4B9HKw0|3Wdgy&>f;RZhjmX#;Ar<#hZl9Dy)_fxwHj~|u7td3mP0)N0ddF`m z(Bct_Fx^mXlc+TCeBVT)Zu;f&K9M=}(D~JsHI1e|a(Goci+yNJ;jcbQy*aB@42&Wv z;KrVbP`CUNRFwm~L{o zLsqO-#yer=szVjVFHqwMJ8uJjL^`g}Ai|#BOLG?0JWe|@xITdtrp;aV>$A`p&P5Ae zxWRqmHz~nedWQFN0Ro4cpKr+#I|2>u&x&m!yi{qpNYP|8>(or$LK8?HJ+2c5*3t?N zAGf67DiJswt4tgey9nt;ORF66n0F2MC-KGNCX=e&+FCU z)2hPDtXpZktn|D1N@`j2bXabBKvy~2mzpfS;WT@#0bA&XJiW_NgxM@=_CPTgPh+L1 zurUYOZS3mvx_Q%_P=P+@ZWha6Noi^)j5p52Fg0n+*02gfI|5@V=LyL(GQ;gTxL)n- zOz*FHY@XMOeMXczZyF`odl5xh2_AQ^Vc>y!Ccm5bK?NHvtFi$_EffRU!_ML>J~_z7 z@we3s{T;@fgz&4IN!ZqhrNiKI8#Cs7&?i z?_UY`_)|dCOdg!nv0rax$l4RbX`=u(V(gJ}^t*m{U;ZCHBgp;i=6Ec9p@CXVb@;DY zjmdU;VkSW2c@U;?rik7>p-K4WX4QTn8qO>H)Lm%nqtTrGmPdCXDex(rx=fb6H+Yhk zP{AJMDdurcP&$o6J~Xjxj0lyuY%=ohhq5G*X$01O7{)vWb6n~bYl2F~C;C*i6&GK1 zvCo$waa1I%!kr9nVQbRx*PjrgU#oGf?)egPj>p3U;=T$r8aSOe>hWr9eT>IEJ#2a! ztK{ygM3AZMdd7LgWC~~<>y!O6gSxEDP_n%na(N|hmEKWL7x#ccubtknB+Hn9^K863 zwD`V3+md`nQy9i&6*o(3t1fbIA&KaV+eLs|-Qqp9;CrOheLRj4w5&=}N&E>jq=kn7 z_l9_y;ro^EL|DK9ZVG@bj#_O|33KlKU1_;G4|Si(kRnE%Mle$X*7(W?Zo|J z4fzq?rE}ajJT1!z_d%=tq0?9$QRWPfh}c&V2W6d*6p}J-uEPT}?j&FdrzT_e?;{&C zw5@{InA;+U_hTP}!KXf2=~ymsT6Wth-<>96KET~JP?>kwfI5^{%MlOcxZBsrEgG68 z>V1VY${>Ox`IN9R2e0)BeI!2t7|cB+o<+S2tVg(MmV@?lcxLv8jP7PzO~vW#nBC|h ze*jq{0c-7hvVC^$Ml{9r-0DYH-ye`nXjrM*vqyK0Cf#pfqvF-#r=ESU>z4gcx_N4( z$?dX>+wd7ECq97Tk}XE9%t)9A)RRX=yUi|-iWc%ze~z6~r6{2GKt73pRH1+Auwc%K zLNnh_)+D-hwDF*(R>p-?u>QvULq)e%tu(2+^ z^v~ah)hPk|xf@}fmYAuXBQ3jOht|KfoRIU_f8=egW^nWkkyx4z?uWkPf!JezSr)`oEtPOh;5f2W zj#1wsD+iBxIp|HJq5YG}7~!WoL`k>p_^>7Kcmq}3$2|G5!LK%F@(2kDA~9-aJki1- zMu0qbG-wm!cH{6H^mkCqXE(g(XiO0zHB5~^^%pN%epPGrvDZsxs@+;3L?3o!(Iy;$ zdIJAiuR_f0mqm0BlsQM6pOiDM_^hGm7b7dhTvz;eO8h` zihpg(7?8S`T_v7dPB5zm)&Qvi)%2i$lzy#!JXw{ngbf}7(Qvsc;y<E9kXbZf7i+`IH#lAsTdFurIA=DX7BlWoWjitfi+>OX|!=*+XK`U!N7tuz$-F4r+G zVgy+t+Y``t>-pF66jnZ(Ybxy_z6esSr_>8d!6&G~?SCsVthIK7JsgVg68%@D^*Ju1 zwsjO7h)4)eE~xVx!Go2eedZ%|k6M5#ytq7=@Sf;n9X~@fE#AGsT8<63rV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..b3bc90c --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #6366f1 + \ No newline at end of file diff --git a/assets/icon/app_icon.png b/assets/icon/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c7e6296c5272743c557ced62d5fb375209f2ed GIT binary patch literal 41214 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°z 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 literal 0 HcmV?d00001 diff --git a/lib/app.dart b/lib/app.dart index fa88276..61f4e82 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -3,15 +3,19 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'core/constants.dart'; +import 'core/exceptions.dart'; +import 'providers/api_client_provider.dart'; import 'providers/auth_provider.dart'; +import 'providers/capture_queue_provider.dart'; +import 'providers/notes_provider.dart'; import 'providers/settings_provider.dart'; +import 'providers/tasks_provider.dart'; import 'screens/auth/login_screen.dart'; import 'screens/chat/chat_screen.dart'; import 'screens/chat/conversations_list_screen.dart'; import 'screens/notes/note_detail_screen.dart'; import 'screens/notes/note_edit_screen.dart'; import 'screens/notes/notes_list_screen.dart'; -import 'screens/quick_capture/quick_capture_screen.dart'; import 'screens/settings/settings_screen.dart'; import 'screens/setup/setup_screen.dart'; import 'screens/splash/splash_screen.dart'; @@ -66,10 +70,6 @@ final routerProvider = Provider((ref) { path: Routes.login, builder: (_, _) => const LoginScreen(), ), - GoRoute( - path: Routes.quickCapture, - builder: (_, _) => const QuickCaptureScreen(), - ), GoRoute( path: Routes.settings, builder: (_, _) => const SettingsScreen(), @@ -146,7 +146,12 @@ class _Shell extends ConsumerWidget { final index = _tabIndex(location); return Scaffold( - body: child, + body: Column( + children: [ + const _QuickCaptureBar(), + Expanded(child: child), + ], + ), bottomNavigationBar: NavigationBar( selectedIndex: index, onDestinationSelected: (i) => context.go(_tabs[i]), @@ -157,12 +162,185 @@ class _Shell extends ConsumerWidget { icon: Icon(Icons.chat_bubble), label: 'Chat'), ], ), - floatingActionButton: FloatingActionButton( - heroTag: 'shell_fab', - onPressed: () => context.push(Routes.quickCapture), - child: const Icon(Icons.add), + ); + } +} + +class _QuickCaptureBar extends ConsumerStatefulWidget { + const _QuickCaptureBar(); + + @override + ConsumerState<_QuickCaptureBar> createState() => _QuickCaptureBarState(); +} + +class _QuickCaptureBarState extends ConsumerState<_QuickCaptureBar> { + final _controller = TextEditingController(); + bool _busy = false; + + @override + void initState() { + super.initState(); + // Retry any offline-queued captures from previous sessions. + WidgetsBinding.instance.addPostFrameCallback((_) => _drainQueue()); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + Future _submit() async { + final text = _controller.text.trim(); + if (text.isEmpty || _busy) return; + + _controller.clear(); + setState(() => _busy = true); + + // Capture the messenger before the async gap so we can show a snackbar + // even if the user has navigated to a deeper view by the time it resolves. + final messenger = ScaffoldMessenger.of(context); + + try { + final result = await ref.read(quickCaptureApiProvider).capture(text); + + switch (result.type) { + case 'note': + ref.invalidate(notesProvider); + case 'task': + case 'todo': + ref.invalidate(tasksProvider); + } + + final msg = result.message.isNotEmpty + ? result.message + : '${_typeLabel(result.type)} created: ${result.title}'; + messenger.showSnackBar( + SnackBar(content: Text(msg), behavior: SnackBarBehavior.floating), + ); + _drainQueue(); // Silently flush any offline-queued captures. + } on NetworkException { + await ref.read(captureQueueProvider.notifier).enqueue(text); + messenger.showSnackBar( + const SnackBar( + content: Text( + "You're offline — capture saved and will retry automatically."), + behavior: SnackBarBehavior.floating, + ), + ); + } on AppException catch (e) { + messenger.showSnackBar( + SnackBar(content: Text(e.message), behavior: SnackBarBehavior.floating), + ); + } catch (_) { + messenger.showSnackBar( + const SnackBar( + content: Text('Capture failed. Please try again.'), + behavior: SnackBarBehavior.floating, + ), + ); + } finally { + if (mounted) setState(() => _busy = false); + } + } + + Future _drainQueue() async { + final queue = ref.read(captureQueueProvider); + if (queue.isEmpty) return; + final api = ref.read(quickCaptureApiProvider); + for (final text in List.from(queue)) { + try { + final result = await api.capture(text); + await ref.read(captureQueueProvider.notifier).dequeue(text); + switch (result.type) { + case 'note': + ref.invalidate(notesProvider); + case 'task': + case 'todo': + ref.invalidate(tasksProvider); + } + } on NetworkException { + break; // Still offline — stop draining. + } catch (_) { + // Server/parse error — remove to avoid infinite retries. + await ref.read(captureQueueProvider.notifier).dequeue(text); + } + } + } + + String _typeLabel(String type) => switch (type) { + 'note' => 'Note', + 'task' => 'Task', + 'event' => 'Event', + 'todo' => 'To-do', + _ => type, + }; + + String _hintForLocation(String location) { + if (location.startsWith(Routes.tasks)) return 'Add a task…'; + if (location.startsWith(Routes.conversations)) return 'Ask Fabled…'; + return 'Capture a note…'; + } + + @override + Widget build(BuildContext context) { + final location = GoRouterState.of(context).matchedLocation; + final queueCount = ref.watch(captureQueueProvider).length; + return SafeArea( + bottom: false, + child: Padding( + padding: const EdgeInsets.fromLTRB(12, 8, 4, 4), + child: Row( + children: [ + Expanded( + child: TextField( + controller: _controller, + enabled: !_busy, + textInputAction: TextInputAction.send, + onSubmitted: (_) => _submit(), + onChanged: (_) => setState(() {}), + decoration: InputDecoration( + hintText: _hintForLocation(location), + isDense: true, + contentPadding: + const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(24), + ), + prefixIcon: _busy + ? const Padding( + padding: EdgeInsets.all(12), + child: SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 2), + ), + ) + : queueCount > 0 + ? Badge( + label: Text('$queueCount'), + child: + const Icon(Icons.cloud_upload_outlined), + ) + : const Icon(Icons.auto_awesome_outlined), + suffixIcon: _controller.text.trim().isNotEmpty && !_busy + ? IconButton( + icon: const Icon(Icons.send), + onPressed: _submit, + tooltip: 'Capture', + ) + : null, + ), + ), + ), + IconButton( + icon: const Icon(Icons.settings_outlined), + tooltip: 'Settings', + onPressed: () => context.push(Routes.settings), + ), + ], + ), ), - floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, ); } } @@ -173,9 +351,11 @@ class FabledApp extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final router = ref.watch(routerProvider); + final themeMode = ref.watch(themeModeProvider); return MaterialApp.router( title: 'Fabled', + themeMode: themeMode, theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo), useMaterial3: true, diff --git a/lib/data/api/chat_api.dart b/lib/data/api/chat_api.dart index 3af7050..4707e16 100644 --- a/lib/data/api/chat_api.dart +++ b/lib/data/api/chat_api.dart @@ -42,17 +42,18 @@ class ChatApi { } } - // Messages are embedded in the conversation detail response. - Future> getMessages(int conversationId) async { + // Returns the conversation metadata AND its messages in a single request. + Future<(Conversation, List)> getMessages(int conversationId) async { try { final response = await _dio.get('/api/chat/conversations/$conversationId'); final conv = response.data as Map; + final conversation = Conversation.fromJson(conv); final list = conv['messages'] as List? ?? []; - return list + final messages = list .map((e) => Message.fromJson(e as Map)) - .where((m) => m.status != 'generating') // skip in-flight placeholders .toList(); + return (conversation, messages); } on DioException catch (e) { throw dioToApp(e); } @@ -77,7 +78,12 @@ class ChatApi { '/api/chat/conversations/$conversationId/generation/stream', options: Options( responseType: ResponseType.stream, - headers: {'Accept': 'text/event-stream'}, + receiveTimeout: Duration.zero, // SSE streams run indefinitely + sendTimeout: Duration.zero, + headers: { + 'Accept': 'text/event-stream', + 'Cache-Control': 'no-cache', + }, ), ); @@ -98,15 +104,19 @@ class ChatApi { if (line.startsWith('event: ')) { currentEvent = line.substring(7).trim(); } else if (line.startsWith('data: ')) { - final jsonStr = line.substring(6).trim(); - if (currentEvent == 'chunk') { + final data = line.substring(6).trim(); + if (data == '[DONE]') return; + if (currentEvent == 'done' || currentEvent == 'error') return; + + // Parse as JSON if possible, otherwise yield raw text. + if (currentEvent == 'chunk' || currentEvent.isEmpty) { try { - final data = json.decode(jsonStr) as Map; - final text = data['text'] as String? ?? ''; + final obj = json.decode(data) as Map; + final text = obj['text'] as String? ?? ''; if (text.isNotEmpty) yield text; - } catch (_) {} - } else if (currentEvent == 'done' || currentEvent == 'error') { - return; + } catch (_) { + if (data.isNotEmpty) yield data; + } } } else if (line.isEmpty) { currentEvent = ''; // blank line = SSE event separator diff --git a/lib/data/api/quick_capture_api.dart b/lib/data/api/quick_capture_api.dart new file mode 100644 index 0000000..19ca190 --- /dev/null +++ b/lib/data/api/quick_capture_api.dart @@ -0,0 +1,49 @@ +import 'package:dio/dio.dart'; + +import 'api_client.dart'; + +/// Result returned by POST /api/quick-capture. +/// type is one of: "note", "task", "event", "todo" +class CaptureResult { + final String type; + final String message; // human-readable summary from the server + final bool fallback; // true when the server used a note as a fallback + final int? id; + final String title; + + const CaptureResult({ + required this.type, + required this.message, + this.fallback = false, + this.id, + required this.title, + }); + + factory CaptureResult.fromJson(Map json) { + final data = json['data'] as Map? ?? {}; + return CaptureResult( + type: json['type'] as String? ?? 'note', + message: json['message'] as String? ?? '', + fallback: json['fallback'] as bool? ?? false, + id: data['id'] as int?, + title: data['title'] as String? ?? '', + ); + } +} + +class QuickCaptureApi { + final Dio _dio; + const QuickCaptureApi(this._dio); + + Future capture(String text) async { + try { + final response = await _dio.post( + '/api/quick-capture', + data: {'text': text}, + ); + return CaptureResult.fromJson(response.data as Map); + } on DioException catch (e) { + throw dioToApp(e); + } + } +} diff --git a/lib/data/models/conversation.dart b/lib/data/models/conversation.dart index 129c528..8edf44e 100644 --- a/lib/data/models/conversation.dart +++ b/lib/data/models/conversation.dart @@ -13,7 +13,7 @@ class Conversation { factory Conversation.fromJson(Map json) => Conversation( id: json['id'] as int, - title: json['title'] as String, + title: json['title'] as String? ?? '', createdAt: DateTime.parse(json['created_at'] as String), updatedAt: DateTime.parse(json['updated_at'] as String), ); diff --git a/lib/data/repositories/chat_repository.dart b/lib/data/repositories/chat_repository.dart index afa2d3b..8d548c0 100644 --- a/lib/data/repositories/chat_repository.dart +++ b/lib/data/repositories/chat_repository.dart @@ -10,7 +10,7 @@ class ChatRepository { Future createConversation(String title) => _api.createConversation(title); Future deleteConversation(int id) => _api.deleteConversation(id); - Future> getMessages(int conversationId) => + Future<(Conversation, List)> getMessages(int conversationId) => _api.getMessages(conversationId); Future sendMessage(int conversationId, String content) => _api.sendMessage(conversationId, content); diff --git a/lib/providers/api_client_provider.dart b/lib/providers/api_client_provider.dart index 8a337a9..2c416c3 100644 --- a/lib/providers/api_client_provider.dart +++ b/lib/providers/api_client_provider.dart @@ -6,6 +6,7 @@ import '../data/api/api_client.dart'; import '../data/api/auth_api.dart'; import '../data/api/chat_api.dart'; import '../data/api/notes_api.dart'; +import '../data/api/quick_capture_api.dart'; import '../data/api/tasks_api.dart'; import '../data/repositories/auth_repository.dart'; import '../data/repositories/chat_repository.dart'; @@ -40,6 +41,10 @@ final chatApiProvider = Provider((ref) { return ChatApi(ref.watch(dioProvider)); }); +final quickCaptureApiProvider = Provider((ref) { + return QuickCaptureApi(ref.watch(dioProvider)); +}); + final authRepositoryProvider = Provider((ref) { return AuthRepository(ref.watch(authApiProvider)); }); diff --git a/lib/providers/capture_queue_provider.dart b/lib/providers/capture_queue_provider.dart new file mode 100644 index 0000000..89f2bcb --- /dev/null +++ b/lib/providers/capture_queue_provider.dart @@ -0,0 +1,29 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import 'settings_provider.dart'; + +final captureQueueProvider = + StateNotifierProvider>( + (ref) => CaptureQueueNotifier(ref.watch(sharedPreferencesProvider)), +); + +class CaptureQueueNotifier extends StateNotifier> { + static const _key = 'capture_queue'; + final SharedPreferences _prefs; + + CaptureQueueNotifier(this._prefs) + : super(_prefs.getStringList(_key) ?? []); + + Future enqueue(String text) async { + final updated = [...state, text]; + await _prefs.setStringList(_key, updated); + state = updated; + } + + Future dequeue(String text) async { + final updated = List.from(state)..remove(text); + await _prefs.setStringList(_key, updated); + state = updated; + } +} diff --git a/lib/providers/chat_provider.dart b/lib/providers/chat_provider.dart index f76c8b8..1d53d05 100644 --- a/lib/providers/chat_provider.dart +++ b/lib/providers/chat_provider.dart @@ -4,6 +4,9 @@ import '../data/models/conversation.dart'; import '../data/models/message.dart'; import 'api_client_provider.dart'; +// Separate StateProvider so UI re-builds immediately when streaming starts/stops. +final isStreamingProvider = StateProvider.family((ref, _) => false); + final conversationsProvider = AsyncNotifierProvider>( ConversationsNotifier.new); @@ -28,71 +31,101 @@ class ConversationsNotifier extends AsyncNotifier> { if (c.id != id) c, ]); } + + // Called after a message is sent to patch the server-generated title + // in-place without triggering a full reload or loading state. + void patchConversation(Conversation updated) { + final list = state.valueOrNull; + if (list == null) return; + state = AsyncData([ + for (final c in list) + if (c.id == updated.id) updated else c, + ]); + } } final messagesProvider = AsyncNotifierProvider.family, int>(MessagesNotifier.new); class MessagesNotifier extends FamilyAsyncNotifier, int> { - bool _isStreaming = false; - bool get isStreaming => _isStreaming; - @override Future> build(int arg) async { - return ref.watch(chatRepositoryProvider).getMessages(arg); + final (_, messages) = + await ref.watch(chatRepositoryProvider).getMessages(arg); + return messages; } Future sendMessage(String content) async { - final conversationId = arg; + final convId = arg; final repo = ref.read(chatRepositoryProvider); + final previousMessages = state.valueOrNull ?? []; - // Optimistically add the user message. + // Optimistic UI: show the user message + assistant placeholder immediately. final userMsg = Message( - conversationId: conversationId, + conversationId: convId, role: MessageRole.user, content: content, ); - state = AsyncData([...state.valueOrNull ?? [], userMsg]); - - // Add an empty assistant placeholder. final placeholder = Message( - conversationId: conversationId, + conversationId: convId, role: MessageRole.assistant, content: '', status: 'generating', ); - state = AsyncData([...state.requireValue, placeholder]); + state = AsyncData([...previousMessages, userMsg, placeholder]); + ref.read(isStreamingProvider(convId).notifier).state = true; - _isStreaming = true; try { - // Step 1: POST the message (fires background generation on server). - await repo.sendMessage(conversationId, content); - - // Step 2: Stream chunks and update the placeholder in place. - await for (final chunk in repo.streamGeneration(conversationId)) { - final msgs = state.requireValue; - final last = msgs.last.copyWith(content: msgs.last.content + chunk); - state = AsyncData([...msgs.sublist(0, msgs.length - 1), last]); - } - - // Mark the assistant message as complete. - final msgs = state.requireValue; - final last = msgs.last.copyWith(status: 'complete'); - state = AsyncData([...msgs.sublist(0, msgs.length - 1), last]); + // ── Step 1: POST the message. If this fails the server never got it. ── + await repo.sendMessage(convId, content); } catch (e) { - // Remove the placeholder on error so the user can retry. - state = AsyncData([ - for (final m in state.valueOrNull ?? []) - if (m.status != 'generating') m, - ]); + state = AsyncData(previousMessages); + ref.read(isStreamingProvider(convId).notifier).state = false; rethrow; + } + + // ── Step 2: Stream the response (best effort — silent on failure). ── + bool streamedContent = false; + try { + await for (final chunk in repo.streamGeneration(convId)) { + streamedContent = true; + final msgs = state.requireValue; + final updated = msgs.last.copyWith(content: msgs.last.content + chunk); + state = AsyncData([...msgs.sublist(0, msgs.length - 1), updated]); + } + } catch (_) { + // SSE failed — fall through to the polling reload below. + } + + // ── Step 3: Poll the API until we have a completed assistant response. + // + // If SSE delivered content the server is done; one reload suffices. + // If SSE delivered nothing, the LLM may still be generating — we retry + // with short delays so the response appears as soon as it's ready. + // A completed message is one whose status is not 'generating'. + try { + final maxAttempts = streamedContent ? 1 : 20; + for (var attempt = 0; attempt < maxAttempts; attempt++) { + if (attempt > 0) await Future.delayed(const Duration(seconds: 2)); + final (conv, fresh) = await repo.getMessages(convId); + state = AsyncData(fresh); + ref.read(conversationsProvider.notifier).patchConversation(conv); + final done = fresh.any( + (m) => m.role == MessageRole.assistant && m.status != 'generating', + ); + if (done) break; + } + } catch (_) { + // If every reload fails, at least clear the generating placeholder. + final msgs = state.valueOrNull; + if (msgs != null && msgs.isNotEmpty && msgs.last.status == 'generating') { + state = AsyncData([ + ...msgs.sublist(0, msgs.length - 1), + msgs.last.copyWith(status: 'complete'), + ]); + } } finally { - _isStreaming = false; + ref.read(isStreamingProvider(convId).notifier).state = false; } } } - -final isStreamingProvider = Provider.family((ref, convId) { - final notifier = ref.watch(messagesProvider(convId).notifier); - return notifier.isStreaming; -}); diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 6421d68..1c0cf54 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -1,7 +1,9 @@ +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; const _kServerUrl = 'server_url'; +const _kThemeMode = 'theme_mode'; final sharedPreferencesProvider = Provider((ref) { throw UnimplementedError('Override in ProviderScope'); @@ -11,6 +13,35 @@ final cookiesPathProvider = Provider((ref) { throw UnimplementedError('Override in ProviderScope'); }); +final themeModeProvider = + StateNotifierProvider((ref) { + final prefs = ref.watch(sharedPreferencesProvider); + return ThemeModeNotifier(prefs); +}); + +class ThemeModeNotifier extends StateNotifier { + final SharedPreferences _prefs; + + ThemeModeNotifier(this._prefs) + : super(_fromString(_prefs.getString(_kThemeMode))); + + static ThemeMode _fromString(String? value) => switch (value) { + 'light' => ThemeMode.light, + 'dark' => ThemeMode.dark, + _ => ThemeMode.system, + }; + + Future setMode(ThemeMode mode) async { + final value = switch (mode) { + ThemeMode.light => 'light', + ThemeMode.dark => 'dark', + _ => 'system', + }; + await _prefs.setString(_kThemeMode, value); + state = mode; + } +} + final serverUrlProvider = StateNotifierProvider((ref) { final prefs = ref.watch(sharedPreferencesProvider); return ServerUrlNotifier(prefs); diff --git a/lib/screens/chat/chat_screen.dart b/lib/screens/chat/chat_screen.dart index 98d3bd8..a12ea46 100644 --- a/lib/screens/chat/chat_screen.dart +++ b/lib/screens/chat/chat_screen.dart @@ -50,6 +50,12 @@ class _ChatScreenState extends ConsumerState { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text(e.message))); } + } catch (_) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Failed to send message.')), + ); + } } } @@ -63,15 +69,26 @@ class _ChatScreenState extends ConsumerState { _scrollToBottom(); }); + final convTitle = ref + .watch(conversationsProvider) + .valueOrNull + ?.where((c) => c.id == widget.conversationId) + .firstOrNull + ?.title; + return Scaffold( - appBar: AppBar(title: const Text('Chat')), + appBar: AppBar( + title: Text(convTitle?.isNotEmpty == true ? convTitle! : 'Chat'), + ), body: Column( children: [ Expanded( child: messagesAsync.when( loading: () => const Center(child: CircularProgressIndicator()), - error: (e, _) => Center(child: Text('Error: $e')), + error: (_, _) => const Center( + child: Text('Could not load messages.'), + ), data: (messages) { if (messages.isEmpty) { return const Center( diff --git a/lib/screens/chat/conversations_list_screen.dart b/lib/screens/chat/conversations_list_screen.dart index 7321d09..28dfbf8 100644 --- a/lib/screens/chat/conversations_list_screen.dart +++ b/lib/screens/chat/conversations_list_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/constants.dart'; +import '../../core/exceptions.dart'; import '../../providers/chat_provider.dart'; class ConversationsListScreen extends ConsumerWidget { @@ -13,14 +14,16 @@ class ConversationsListScreen extends ConsumerWidget { final convsAsync = ref.watch(conversationsProvider); return Scaffold( - appBar: AppBar(title: const Text('Chat')), body: convsAsync.when( loading: () => const Center(child: CircularProgressIndicator()), - error: (e, _) => Center( + error: (_, _) => Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text('Error: $e'), + const Icon(Icons.cloud_off, size: 48), + const SizedBox(height: 12), + const Text('Could not load conversations.'), + const SizedBox(height: 4), TextButton( onPressed: () => ref.invalidate(conversationsProvider), child: const Text('Retry'), @@ -42,10 +45,14 @@ class ConversationsListScreen extends ConsumerWidget { final conv = convs[i]; return ListTile( leading: const Icon(Icons.chat_bubble_outline), - title: Text(conv.title), + title: Text( + conv.title.isNotEmpty ? conv.title : 'New conversation', + ), subtitle: Text( conv.updatedAt.toLocal().toString().substring(0, 16), - style: Theme.of(context).textTheme.bodySmall, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), ), onTap: () => context.push( Routes.chat.replaceFirst(':id', '${conv.id}'), @@ -53,16 +60,21 @@ class ConversationsListScreen extends ConsumerWidget { onLongPress: () async { final confirm = await showDialog( context: context, - builder: (_) => AlertDialog( + builder: (dialogContext) => AlertDialog( title: const Text('Delete conversation?'), - content: Text(conv.title), + content: Text( + conv.title.isNotEmpty + ? conv.title + : 'New conversation', + ), actions: [ TextButton( - onPressed: () => Navigator.pop(context, false), + onPressed: () => + Navigator.pop(dialogContext, false), child: const Text('Cancel'), ), TextButton( - onPressed: () => Navigator.pop(context, true), + onPressed: () => Navigator.pop(dialogContext, true), child: const Text('Delete'), ), ], @@ -89,34 +101,16 @@ class ConversationsListScreen extends ConsumerWidget { } Future _newConversation(BuildContext context, WidgetRef ref) async { - final controller = TextEditingController(); - final title = await showDialog( - context: context, - builder: (_) => AlertDialog( - title: const Text('New Conversation'), - content: TextField( - controller: controller, - decoration: const InputDecoration(hintText: 'Title'), - autofocus: true, - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: const Text('Cancel'), - ), - TextButton( - onPressed: () => Navigator.pop(context, controller.text.trim()), - child: const Text('Create'), - ), - ], - ), - ); - if (title != null && title.isNotEmpty) { - final conv = - await ref.read(conversationsProvider.notifier).create(title); + try { + final conv = await ref.read(conversationsProvider.notifier).create(''); if (context.mounted) { context.push(Routes.chat.replaceFirst(':id', '${conv.id}')); } + } on AppException catch (e) { + if (context.mounted) { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text(e.message))); + } } } } diff --git a/lib/screens/notes/note_edit_screen.dart b/lib/screens/notes/note_edit_screen.dart index 6381bd5..51f3fcd 100644 --- a/lib/screens/notes/note_edit_screen.dart +++ b/lib/screens/notes/note_edit_screen.dart @@ -41,6 +41,30 @@ class _NoteEditScreenState extends ConsumerState { _loaded = true; } + Future _delete() async { + final confirm = await showDialog( + context: context, + builder: (dialogContext) => AlertDialog( + title: const Text('Delete note?'), + content: Text(_titleController.text), + actions: [ + TextButton( + onPressed: () => Navigator.pop(dialogContext, false), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () => Navigator.pop(dialogContext, true), + child: const Text('Delete'), + ), + ], + ), + ); + if (confirm == true) { + await ref.read(notesProvider.notifier).delete(widget.noteId!); + if (mounted) context.pop(); + } + } + Future _save() async { final title = _titleController.text.trim(); final body = _contentController.text; @@ -79,6 +103,12 @@ class _NoteEditScreenState extends ConsumerState { appBar: AppBar( title: Text(widget.noteId == null ? 'New Note' : 'Edit Note'), actions: [ + if (widget.noteId != null) + IconButton( + icon: const Icon(Icons.delete_outline), + tooltip: 'Delete', + onPressed: _delete, + ), IconButton( icon: Icon(_preview ? Icons.edit : Icons.preview), tooltip: _preview ? 'Edit' : 'Preview', diff --git a/lib/screens/notes/notes_list_screen.dart b/lib/screens/notes/notes_list_screen.dart index c43d1c2..2835939 100644 --- a/lib/screens/notes/notes_list_screen.dart +++ b/lib/screens/notes/notes_list_screen.dart @@ -5,22 +5,63 @@ import 'package:go_router/go_router.dart'; import '../../core/constants.dart'; import '../../providers/notes_provider.dart'; -class NotesListScreen extends ConsumerWidget { +class NotesListScreen extends ConsumerStatefulWidget { const NotesListScreen({super.key}); @override - Widget build(BuildContext context, WidgetRef ref) { + ConsumerState createState() => _NotesListScreenState(); +} + +class _NotesListScreenState extends ConsumerState { + bool _showSearch = false; + String _search = ''; + + @override + Widget build(BuildContext context) { final notesAsync = ref.watch(notesProvider); return Scaffold( - appBar: AppBar(title: const Text('Notes')), + appBar: AppBar( + automaticallyImplyLeading: false, + title: _showSearch + ? TextField( + autofocus: true, + decoration: const InputDecoration( + hintText: 'Search notes…', + border: InputBorder.none, + ), + onChanged: (v) => + setState(() => _search = v.trim().toLowerCase()), + ) + : null, + actions: [ + if (_showSearch) + IconButton( + icon: const Icon(Icons.close), + tooltip: 'Close search', + onPressed: () => setState(() { + _showSearch = false; + _search = ''; + }), + ) + else + IconButton( + icon: const Icon(Icons.search), + tooltip: 'Search', + onPressed: () => setState(() => _showSearch = true), + ), + ], + ), body: notesAsync.when( loading: () => const Center(child: CircularProgressIndicator()), - error: (e, _) => Center( + error: (_, _) => Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text('Error: $e'), + const Icon(Icons.cloud_off, size: 48), + const SizedBox(height: 12), + const Text('Could not load notes.'), + const SizedBox(height: 4), TextButton( onPressed: () => ref.invalidate(notesProvider), child: const Text('Retry'), @@ -29,21 +70,46 @@ class NotesListScreen extends ConsumerWidget { ), ), data: (notes) { - if (notes.isEmpty) { - return const Center(child: Text('No notes yet. Tap + to create one.')); + final filtered = _search.isEmpty + ? notes + : notes + .where((n) => + n.title.toLowerCase().contains(_search) || + n.body.toLowerCase().contains(_search)) + .toList(); + + if (filtered.isEmpty) { + return Center( + child: Text( + _search.isEmpty + ? 'No notes yet. Tap + to create one.' + : 'No notes match "$_search".', + ), + ); } + return RefreshIndicator( onRefresh: () => ref.refresh(notesProvider.future), child: ListView.separated( - itemCount: notes.length, + itemCount: filtered.length, separatorBuilder: (_, _) => const Divider(height: 1), itemBuilder: (context, i) { - final note = notes[i]; + final note = filtered[i]; + final preview = note.body + .split('\n') + .firstWhere((l) => l.trim().isNotEmpty, orElse: () => '') + .trim(); return ListTile( title: Text(note.title), subtitle: Text( - note.updatedAt.toLocal().toString().substring(0, 16), - style: Theme.of(context).textTheme.bodySmall, + preview.isNotEmpty + ? preview + : note.updatedAt.toLocal().toString().substring(0, 16), + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), onTap: () => context.push( Routes.noteDetail.replaceFirst(':id', '${note.id}'), diff --git a/lib/screens/quick_capture/quick_capture_screen.dart b/lib/screens/quick_capture/quick_capture_screen.dart index ea245e9..15dbeee 100644 --- a/lib/screens/quick_capture/quick_capture_screen.dart +++ b/lib/screens/quick_capture/quick_capture_screen.dart @@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/exceptions.dart'; -import '../../data/models/task.dart'; +import '../../providers/api_client_provider.dart'; import '../../providers/notes_provider.dart'; import '../../providers/tasks_provider.dart'; @@ -15,182 +15,137 @@ class QuickCaptureScreen extends ConsumerStatefulWidget { _QuickCaptureScreenState(); } -class _QuickCaptureScreenState extends ConsumerState - with SingleTickerProviderStateMixin { - late final TabController _tabs; - final _noteTitleController = TextEditingController(); - final _noteContentController = TextEditingController(); - final _taskTitleController = TextEditingController(); - TaskPriority _taskPriority = TaskPriority.medium; - bool _saving = false; - - @override - void initState() { - super.initState(); - _tabs = TabController(length: 2, vsync: this); - } +class _QuickCaptureScreenState extends ConsumerState { + final _controller = TextEditingController(); + final _focusNode = FocusNode(); + bool _loading = false; @override void dispose() { - _tabs.dispose(); - _noteTitleController.dispose(); - _noteContentController.dispose(); - _taskTitleController.dispose(); + _controller.dispose(); + _focusNode.dispose(); super.dispose(); } - Future _saveNote() async { - final title = _noteTitleController.text.trim(); - if (title.isEmpty) { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar(content: Text('Title is required.'))); - return; - } - setState(() => _saving = true); + Future _send() async { + final text = _controller.text.trim(); + if (text.isEmpty) return; + setState(() => _loading = true); try { - await ref - .read(notesProvider.notifier) - .create(title, _noteContentController.text); - if (mounted) context.pop(); + final result = + await ref.read(quickCaptureApiProvider).capture(text); + // Invalidate the relevant provider so the list screen re-fetches. + switch (result.type) { + case 'note': + ref.invalidate(notesProvider); + case 'task': + case 'todo': + ref.invalidate(tasksProvider); + } + + if (mounted) { + // Use the server's human-readable message if available, else compose one. + final msg = result.message.isNotEmpty + ? result.message + : '${_typeLabel(result.type)} created: ${result.title}'; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(msg), + behavior: SnackBarBehavior.floating, + ), + ); + context.pop(); + } } on AppException catch (e) { if (mounted) { - ScaffoldMessenger.of(context) - .showSnackBar(SnackBar(content: Text(e.message))); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(e.message), + behavior: SnackBarBehavior.floating, + ), + ); } } finally { - if (mounted) setState(() => _saving = false); + if (mounted) setState(() => _loading = false); } } - Future _saveTask() async { - final title = _taskTitleController.text.trim(); - if (title.isEmpty) { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar(content: Text('Title is required.'))); - return; - } - setState(() => _saving = true); - try { - await ref.read(tasksProvider.notifier).create( - title: title, - status: TaskStatus.todo, - priority: _taskPriority, - ); - if (mounted) context.pop(); - } on AppException catch (e) { - if (mounted) { - ScaffoldMessenger.of(context) - .showSnackBar(SnackBar(content: Text(e.message))); - } - } finally { - if (mounted) setState(() => _saving = false); - } - } + String _typeLabel(String type) => switch (type) { + 'note' => 'Note', + 'task' => 'Task', + 'event' => 'Event', + 'todo' => 'To-do', + _ => type, + }; @override Widget build(BuildContext context) { + final theme = Theme.of(context); + return Scaffold( - appBar: AppBar( - title: const Text('Quick Capture'), - bottom: TabBar( - controller: _tabs, - tabs: const [Tab(text: 'Note'), Tab(text: 'Task')], + appBar: AppBar(title: const Text('Quick Capture')), + body: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + 'What\'s on your mind?', + style: theme.textTheme.titleMedium, + ), + const SizedBox(height: 4), + Text( + 'Describe a note, task, event, or research item — Fabled will figure out the rest.', + style: theme.textTheme.bodySmall?.copyWith( + color: theme.colorScheme.onSurfaceVariant, + ), + ), + const SizedBox(height: 16), + TextField( + controller: _controller, + focusNode: _focusNode, + autofocus: true, + enabled: !_loading, + maxLines: 6, + minLines: 3, + keyboardType: TextInputType.multiline, + decoration: InputDecoration( + hintText: + 'e.g. "Remind me to call the dentist next Monday" or "Note: project meeting went well, key points were..."', + border: const OutlineInputBorder(), + alignLabelWithHint: true, + suffixIcon: _controller.text.isNotEmpty + ? IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + _controller.clear(); + setState(() {}); + }, + ) + : null, + ), + onChanged: (_) => setState(() {}), + ), + const SizedBox(height: 16), + FilledButton.icon( + onPressed: (_loading || _controller.text.trim().isEmpty) + ? null + : _send, + icon: _loading + ? const SizedBox( + width: 18, + height: 18, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Colors.white, + ), + ) + : const Icon(Icons.auto_awesome), + label: Text(_loading ? 'Processing...' : 'Capture'), + ), + ], ), ), - body: TabBarView( - controller: _tabs, - children: [ - // Note tab - Padding( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - TextField( - controller: _noteTitleController, - decoration: const InputDecoration( - labelText: 'Title', - border: OutlineInputBorder(), - ), - textInputAction: TextInputAction.next, - autofocus: true, - ), - const SizedBox(height: 12), - Expanded( - child: TextField( - controller: _noteContentController, - decoration: const InputDecoration( - hintText: 'Content (optional, supports markdown)', - border: OutlineInputBorder(), - alignLabelWithHint: true, - ), - maxLines: null, - expands: true, - textAlignVertical: TextAlignVertical.top, - keyboardType: TextInputType.multiline, - ), - ), - const SizedBox(height: 12), - SizedBox( - width: double.infinity, - child: FilledButton( - onPressed: _saving ? null : _saveNote, - child: _saving - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : const Text('Save Note'), - ), - ), - ], - ), - ), - // Task tab - Padding( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - TextField( - controller: _taskTitleController, - decoration: const InputDecoration( - labelText: 'Task title', - border: OutlineInputBorder(), - ), - autofocus: true, - ), - const SizedBox(height: 12), - DropdownButtonFormField( - initialValue: _taskPriority, - decoration: const InputDecoration( - labelText: 'Priority', - border: OutlineInputBorder(), - ), - items: TaskPriority.values - .map((p) => - DropdownMenuItem(value: p, child: Text(p.label))) - .toList(), - onChanged: (v) => setState(() => _taskPriority = v!), - ), - const SizedBox(height: 16), - SizedBox( - width: double.infinity, - child: FilledButton( - onPressed: _saving ? null : _saveTask, - child: _saving - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : const Text('Save Task'), - ), - ), - ], - ), - ), - ], - ), ); } } diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart index f48406f..3ea70dc 100644 --- a/lib/screens/settings/settings_screen.dart +++ b/lib/screens/settings/settings_screen.dart @@ -12,6 +12,7 @@ class SettingsScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final serverUrl = ref.watch(serverUrlProvider); + final themeMode = ref.watch(themeModeProvider); return Scaffold( appBar: AppBar(title: const Text('Settings')), @@ -24,6 +25,33 @@ class SettingsScreen extends ConsumerWidget { onTap: () => context.go(Routes.setup), ), const Divider(), + ListTile( + title: const Text('Appearance'), + leading: const Icon(Icons.brightness_6), + trailing: SegmentedButton( + segments: const [ + ButtonSegment( + value: ThemeMode.system, + icon: Icon(Icons.brightness_auto), + tooltip: 'System', + ), + ButtonSegment( + value: ThemeMode.light, + icon: Icon(Icons.light_mode), + tooltip: 'Light', + ), + ButtonSegment( + value: ThemeMode.dark, + icon: Icon(Icons.dark_mode), + tooltip: 'Dark', + ), + ], + selected: {themeMode}, + onSelectionChanged: (modes) => + ref.read(themeModeProvider.notifier).setMode(modes.first), + ), + ), + const Divider(), ListTile( title: const Text('Sign Out'), leading: const Icon(Icons.logout), diff --git a/lib/screens/tasks/task_edit_screen.dart b/lib/screens/tasks/task_edit_screen.dart index ddaae41..1a87f79 100644 --- a/lib/screens/tasks/task_edit_screen.dart +++ b/lib/screens/tasks/task_edit_screen.dart @@ -85,14 +85,15 @@ class _TaskEditScreenState extends ConsumerState { Future _delete() async { final confirm = await showDialog( context: context, - builder: (_) => AlertDialog( + builder: (dialogContext) => AlertDialog( title: const Text('Delete task?'), + content: Text(_titleController.text), actions: [ TextButton( - onPressed: () => Navigator.pop(context, false), + onPressed: () => Navigator.pop(dialogContext, false), child: const Text('Cancel')), TextButton( - onPressed: () => Navigator.pop(context, true), + onPressed: () => Navigator.pop(dialogContext, true), child: const Text('Delete')), ], ), diff --git a/lib/screens/tasks/tasks_list_screen.dart b/lib/screens/tasks/tasks_list_screen.dart index 176536e..0d5594f 100644 --- a/lib/screens/tasks/tasks_list_screen.dart +++ b/lib/screens/tasks/tasks_list_screen.dart @@ -16,6 +16,8 @@ class TasksListScreen extends ConsumerStatefulWidget { class _TasksListScreenState extends ConsumerState with SingleTickerProviderStateMixin { late final TabController _tabs; + bool _showSearch = false; + String _search = ''; @override void initState() { @@ -35,7 +37,35 @@ class _TasksListScreenState extends ConsumerState return Scaffold( appBar: AppBar( - title: const Text('Tasks'), + automaticallyImplyLeading: false, + title: _showSearch + ? TextField( + autofocus: true, + decoration: const InputDecoration( + hintText: 'Search tasks…', + border: InputBorder.none, + ), + onChanged: (v) => + setState(() => _search = v.trim().toLowerCase()), + ) + : null, + actions: [ + if (_showSearch) + IconButton( + icon: const Icon(Icons.close), + tooltip: 'Close search', + onPressed: () => setState(() { + _showSearch = false; + _search = ''; + }), + ) + else + IconButton( + icon: const Icon(Icons.search), + tooltip: 'Search', + onPressed: () => setState(() => _showSearch = true), + ), + ], bottom: TabBar( controller: _tabs, tabs: const [ @@ -47,11 +77,14 @@ class _TasksListScreenState extends ConsumerState ), body: tasksAsync.when( loading: () => const Center(child: CircularProgressIndicator()), - error: (e, _) => Center( + error: (_, _) => Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text('Error: $e'), + const Icon(Icons.cloud_off, size: 48), + const SizedBox(height: 12), + const Text('Could not load tasks.'), + const SizedBox(height: 4), TextButton( onPressed: () => ref.invalidate(tasksProvider), child: const Text('Retry'), @@ -60,21 +93,29 @@ class _TasksListScreenState extends ConsumerState ), ), data: (tasks) { + final filtered = _search.isEmpty + ? tasks + : tasks + .where((t) => + t.title.toLowerCase().contains(_search) || + (t.description ?? '').toLowerCase().contains(_search)) + .toList(); + final todo = - tasks.where((t) => t.status == TaskStatus.todo).toList(); + filtered.where((t) => t.status == TaskStatus.todo).toList(); final inProgress = - tasks.where((t) => t.status == TaskStatus.inProgress).toList(); + filtered.where((t) => t.status == TaskStatus.inProgress).toList(); final done = - tasks.where((t) => t.status == TaskStatus.done).toList(); + filtered.where((t) => t.status == TaskStatus.done).toList(); return RefreshIndicator( onRefresh: () => ref.refresh(tasksProvider.future), child: TabBarView( controller: _tabs, children: [ - _TaskList(tasks: todo), - _TaskList(tasks: inProgress), - _TaskList(tasks: done), + _TaskList(tasks: todo, search: _search), + _TaskList(tasks: inProgress, search: _search), + _TaskList(tasks: done, search: _search), ], ), ); @@ -91,12 +132,17 @@ class _TasksListScreenState extends ConsumerState class _TaskList extends ConsumerWidget { final List tasks; - const _TaskList({required this.tasks}); + final String search; + const _TaskList({required this.tasks, this.search = ''}); @override Widget build(BuildContext context, WidgetRef ref) { if (tasks.isEmpty) { - return const Center(child: Text('No tasks here.')); + return Center( + child: Text( + search.isEmpty ? 'No tasks here.' : 'No tasks match "$search".', + ), + ); } return ListView.separated( itemCount: tasks.length, @@ -107,7 +153,8 @@ class _TaskList extends ConsumerWidget { leading: _priorityIcon(task.priority), title: Text(task.title), subtitle: task.dueDate != null - ? Text('Due: ${task.dueDate!.toLocal().toString().substring(0, 10)}') + ? Text( + 'Due: ${task.dueDate!.toLocal().toString().substring(0, 10)}') : null, onTap: () => context.push( Routes.taskEdit.replaceFirst(':id', '${task.id}'), diff --git a/pubspec.lock b/pubspec.lock index 3095666..a2db2d8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff + url: "https://pub.dev" + source: hosted + version: "4.0.9" args: dependency: transitive description: @@ -33,6 +41,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" clock: dependency: transitive description: @@ -198,6 +222,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.0" + flutter_launcher_icons: + dependency: "direct dev" + description: + name: flutter_launcher_icons + sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7" + url: "https://pub.dev" + source: hosted + version: "0.14.4" flutter_lints: dependency: "direct dev" description: @@ -264,6 +296,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce + url: "https://pub.dev" + source: hosted + version: "4.8.0" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 + url: "https://pub.dev" + source: hosted + version: "4.11.0" leak_tracker: dependency: transitive description: @@ -416,6 +464,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" + url: "https://pub.dev" + source: hosted + version: "7.0.2" platform: dependency: transitive description: @@ -432,6 +488,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + posix: + dependency: transitive + description: + name: posix + sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" + url: "https://pub.dev" + source: hosted + version: "6.5.0" pub_semver: dependency: transitive description: @@ -613,6 +677,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c7224a8..a9c4a40 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,18 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^6.0.0 + flutter_launcher_icons: ^0.14.3 + +flutter_launcher_icons: + android: true + ios: false + remove_alpha_ios: false + image_path: "assets/icon/app_icon.png" + adaptive_icon_background: "#6366f1" + adaptive_icon_foreground: "assets/icon/app_icon_fg.png" + min_sdk_android: 21 flutter: uses-material-design: true + assets: + - assets/icon/