From 2ce6ca92d7061d19474c3e4dd0c61cdb6793940b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Fri, 18 Jun 2021 21:08:22 +0200 Subject: [PATCH] Mark conflicts in board --- android/gradle.properties | 4 +- assets/icons/button_back.png | Bin 0 -> 3739 bytes assets/icons/button_show_conflicts.png | Bin 0 -> 2929 bytes icons/build_game_icons.sh | 2 + icons/button_back.svg | 2 + icons/button_show_conflicts.svg | 2 + lib/entities/cell.dart | 26 +++++- lib/provider/data.dart | 7 ++ lib/screens/home.dart | 115 +++++++++++++++++++------ 9 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 assets/icons/button_back.png create mode 100644 assets/icons/button_show_conflicts.png create mode 100644 icons/button_back.svg create mode 100644 icons/button_show_conflicts.svg diff --git a/android/gradle.properties b/android/gradle.properties index d9abd55..6638812 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -app.versionName=0.0.12 -app.versionCode=12 +app.versionName=0.0.13 +app.versionCode=13 diff --git a/assets/icons/button_back.png b/assets/icons/button_back.png new file mode 100644 index 0000000000000000000000000000000000000000..370c0893bebe5c38c698f1c04c58a341efcb0707 GIT binary patch literal 3739 zcmeAS@N?(olHy`uVBq!ia0y~yU^oE69Bd2>3_*8t*cliYI14-?iy0W?oEaG8oERJS zYjH3zFi4iTMwA5Sr<If^7Ns(jmzV2h=4BTrCl;jY<rk&TerF@az`&>B>EaktaqI2e z%n7ogqQ~oJwx~`J?T}YkpyVwmpg7s!uR_KI2M3-d0$w`Z4ky)iKVsKm;Z*f9QJYz( ze0qVrfPkWqf&-I~*iCK^9Y@^-hx|@X^060S@;sq(p1+p)@q{yF`QLZf{{FvuSG-!K z_x$32e}CPnez#MhMZk$ektjl`ppEf2<K;$qM#BQ-0{ss>A2vzKI-Kq4)2pv%+i`r4 zn%R59yL+A+%nbi=gd;(#Kyw2_1?LThE5=f<&!*qu`g5n|8^=z^Cr1Mwcoe7CiM=>u zaO1a?)!FjSM&&c*B8MbzGcIT7ZtS<^_;K&p@dHW^*bijv^yg_=+aT<tP#e^+;QpNm z?mN6S*JCCN*ltocV2_A=021T;BX+|%PwehYmNVa<%(Q#GkuieFXY%c%flDs;eVx>| z+$Tui>)65r!m50K-aRgSAkgai<4vAismPbva^4MvT$4XY<W0KmFY=^zmgTJ8u({0- zJsy~{mhC@Y@8NCW;wb4G<-a&#o3uH@ViCWii=3h&mNAqW-(yhIUh^lNqkuK@;tZzi zwP!EtHy-3NwwGkKd64;`hDC>c8WTTbIiorA+q645|GrK5X@C0T_IDYa8=4QD)mNJ_ z|D_xIajge+3wSN0EqHz?8DubAH#xEAo5AO}+-G~kD+}hXXFkhiZ9gOL-G*L{meOZ^ zw%jwE>{!#CeLloyygRm9TH{-?NL}yKnosNRM>_9Pe46oR#a{U=rozUbd6myupKJ0+ zA5OKju3jm4N1{L1h-*e-out{5jM<S~$NxyU?E0;_-hIw%&9uq`_m&j@cwMw9)aF2p z`xoOM>(9P4d@hx6ogru2>Y15QvzzbUQf<mv`Rs#Fwd#i8hHcW^F;kt-iD>(5ei$xk zohMn~!1-o}{LSf2@#_joPxl*_gq>B{o*MN~CS}r7o$Ym5WhVqLpIo;k(e7#7RT*ci zrL(U-esYm3-db(KS*7b)4|HaJ4?d?j+q5M#<7mZ!9R5AC8iV6lqf+jjH=MVHO|#qU zlA%%le+ed=8I8vOnxZ(r9pShn`c#MOMTqMy{<PEwEtL+FeQs;}rfj~jV&+1-B7?l= ztIQdUQ?Jz(+vT0syteq9@Lr>?Emy8R^*NGh^t!>4bNf<}{7K)UL}x$r-?8?wWtiI5 zXA#HupD;hMWcD+U<NdbFPb@iSaq;8h3Ac>OlA|ApwzK_P>GNt%cfsz(KDF(;46c97 z@y}ej-8?@qJ6~?*#oN1e+~%y^;D1xNT=w>};6p3VRn2wWn)S3N$~0=)k-&5z_pd5_ zVP!{j)vf-mP`k5Mc#UdqXk?X`rO}HbuN^18#(iyAfA!G|N8vAbk6)Ioc~bCz)!i;S z;@bmzk@Bs!zo(xp(7w%g%dk`XZS1=r^QE_1M9sQ*-2CynvW%jctPfV{{XMfu;?3Nf zzw@G3yNRn6emVGz$)25&Vb1Fl<^5AlfAkln9EkS%ILChSvc7AldQ{f!xf=c8xe7x; zxR>qL9;SjqBX9Q1s~HzcLKbU!%Gln%e&Bo{Lvq8BM)~<V(I4a=y*O8xb;8YSmG0w7 z7ExF3gJc=(OP-u=KCRNQTUO#tCez$cZ)QZ_T)Ca)x-z55OzRzM?cZy7e|X>dcT<)6 z%V+N{sqK*COnAIzLhjxRRbE9ctGh$*Z!-|S^CDNg@je5i!>uCM)ra?PP~E`vds(RU zG~0t;0~nGw#!E+dK2X0^fBs<XqgM(-cXkSY-{x6hE5fj3?!%nF)io!Wb{xNCF`pqm ztm*YyhO(n|%xC8=Wc#1-=67(MxI@$L#A}WB9T**UJv_S2L+?av^75qpCsWryQr$7R z{mP?hmt)m;$Z;pkX^z}C`Rk9*KR;$T3g3DDiSG{^H^Zf0a?<hlMWa6OAN_Y>`{nMU zjoQy$A6IJx>NPXugtyx>ZR7J~*w&iATJu2SS<kJhIdPopo-;|jP4N1%VFF9S?x}hE z&Wmq<bn4{cNfxta9=Ukjj%6P^Q^OYS`Mu|#x2ZHd*XjM3dtUfXc@0;MKTE-urRS%& z3jI;un4Q1x*74_#lOO!MeEh(77l!EM@|JA%m)}kwO1}O6dEI)UJ3E%{4C|HqWck5X zkl}{8#XO-VhO{WDhw1ZFcf9Tv_%n~=L6Z0Vc$p@KyzM4VuAF&^tOWrlCd=18P32~; zVaT~Sfo1#NO78i>cbYg7IzB#h`1{}KVspJk+382$H4o};VNkG@IjkmlZ`lbZiTt0! zH)drw-7Y)O(r582`XcjvW5yfn7~ck`Fv@r{{`#v@toANu3(Ix~CX3lZ<&*Xu`1EN1 z%;2WoR!a_i_hAUuNnUW_Iq&Uxrlw|>S+<*2nI8cOTSp%|Fh_~|!Fe(9eO+H%iobK_ zZT+-<0?2G0Cc7;i%}(<*K8JU6*Wb&0uwBl=a0$qKh9BEqWpwm5G5pIbeCV%vkk^fY zKlwVt+6{YB3Lo-E_-6k5wcw#=%*?xj?%Aire#mh>FzdFc*m#1eVlvy-Q>#N4x2E#e z@Us@ob(Pr@mcqE_cE^+Di@zS|Oy#dT&r-0~Rc23Y3ge#i!iV9!KX%&p=}lnRBjhmK zRYt{C?7(kcL5J+q{wfU#ECH951L|1~-XG{<S>V1PNd2H^_Lc~y0HK&$nHQp}Kc7%p zw?(aROBmAylZ?d?*Iu-4h_cC?9u>3Gu5&T3ki+4MB^L`XX#CM^T@l9T@#vJYkb|>E zuI3TniZGt=)oz!q9=%ZIR4~u!ez;D56GPO;9WuL=`@%dJW(L11%2;oHWKaFoB^PDa zUew9$I4N?Q*YLSmBtz>BA<3*oYjh{}E)SUf=(5zJY3-^E%coQY*C^gzbY<1WEm5XX zdW;qax9Oe=;OaY@bfev5mtk1rcV6}j60a+n4y1`*SbnWzwQ571@yScyx3?%Xcylha z%wyahR;AG39Z(#zOem=O3sY(TX9ouU$Y1|12(TC&QZY7TPpO#B@v@;OZlkS2vTUQw z1jY|J9mNOtl~2gqz|gnx%g-Ptr}igP{Ta3gJre48S9AK3gsZh$Y3)hY2ajf4(NyGI z5W}8&T=%S%#_dzrS2wKX=s7ygt#V6-c#hE1=Uy5O$8~FK)ftPrmIj(JRExe{w0n-~ zpE6Gt1HRp#rdt&RbudZruGwmGrqp%skMgwlyL0b#7B#aJG%xMHK4G4&tV*{|?`FOq zMH6{17;fJ**>j3Dv&eyU$K1{A_BA(H9=v2x`rwrS&%`rxca#gccQXke*vj{(I_3n^ z4WWpK57dj62k;~bJxym8I1s@eJYU;+&fk~kWZ26)@3*E*_~kRpDoWcpM*Wl}_k%3< zy1BlbH-sbdGgtT}{J+5S`P`e@?Q269b5FMTwIG3MMnml0@ViHjyqnTuEqh0I9@{J@ zlfKn1mg<ZqjQ&<1p65>K$hR<vkhRcFQC7V=t<W=O=j~#~IWJF4XAd%(SC+7aFQNSc zZ>rGK`U;H(!zF)z=l=a+q58zby}a*ds=>AN&Z4Kf{VW>}OyuWZyu{|siH7v4M-%e5 zn&)4>?qZqDIOq9^^8UaizQU9vR~653eLZq&TXWeP-N17J48j}cf4*<A&+la9ixU%0 zbM9zMDZX+`E8h1}#>q672}dP&ANH*Nw)?|PCYIgF@haO3?|3Z;UTph}y_8LL?bP5& z7FAlEi%UIau1>!8;%=1buYHgEvkvV$>w8`F?|O|t!F7*MtSD8`+pPHdbHDtYkZ8A* zFW++c{+6^J`e(e2F|I7*PIpSs^O#2$?AJ3LPPz2|IY&F&J%%}2ldY23zRix=)pt1c zl5g=|XXW+Ex##uX{NVdmYUh}fb*g#dlH*CcjLOtmZ~44eR8QQ0aOvxc=92UUFB(1j z-djjF%rwg0zw^S!<nvXRqzo>y>y>Bx=w0l^x!i-@LHK1I_w{ereOJiy9DA40I!`Rl z?bIGyyQX{d8t=ZpdUpB$9QHkv8ja(am1ce~?m7O>VDh{-dz;T#7c5_M>VRf;Lvc!+ zg6;9|Hh0z@E4P1`UO)3jUuNIrNAH#jCwt}G)_<^WOJcBbfxBkS-2yi^zg5id8K2MI zv)HHe9nU2_p2(Y_`!}%8kbGq|ZK{g-4SDnGifXCpnlYOfnkFAFowV)y4NHgHZ<)3v z-=Da6yP<#LtlUFozQ_31%x?Mcy(MtnZs`y0J(KRddo1->dE!QnXHOrT>HX?r&QvXa z!SDBs_xEN_Ui(b*$LFWwmX>9YE1I^jo+y*Monn3I??wM7InuVD%{z*V_8cyab&g>0 zQNMfqLdG`3`%kyckt^Qy+$UX=NBVTggZ-A)`(7(w3Q7=rIWw%%q)e8{WU|<5-GlEm zf^H}GEYtk+C&4D~^orc3M~s(}HWhoA*VSY;oImFKY->C7^I6|(8gjypv2R-Jt-WX7 zM%#k<><2fl{Al>WCX;_o>jB?1uT8Iaocwb;`2aWXp3UEvZpf`}ojsq&>}28c<p+bG zT+Ezw_aK+?|IUKlC-=R1Tzcies)C+FZ{;3u>a$;DE7JOm!(ZshqTcW`JhM3(5|^Ca zeobq`?=9yHx$Uo6v?P})=PqC8aR18=?ycH7tdkqvML*2%bD#2L+T@if@zU=<SIiNT z_fxc6eDjRN)Wp9Ddn>QZRNCJC?u}zr*xN1!=Krz9xw}uFU1YwErBB`VTq*C-c^4x& zWYX7pcGMYjS=_WSs|jgX5TDvoJ?ZB=CyV6lORvuCTr&Gb?FmV<X({IoIp2mAO+L|` zsP;lnEjGTwFgdVfQdrkH^ZAynvL=c)$r>-~?qn{Jz5a~RoT0mMxyNn(eK|sJXGv<G zxgTfrKYe56S)0#tm(Nu5O|5JdAi4{d@sEAp)QL6=&&=&$U|?YIboFyt=akR{03ELD AbN~PV literal 0 HcmV?d00001 diff --git a/assets/icons/button_show_conflicts.png b/assets/icons/button_show_conflicts.png new file mode 100644 index 0000000000000000000000000000000000000000..060a9da706a71e0d67272f42f2a2d3b3c7bc8dce GIT binary patch literal 2929 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 F0st=NxxfGb literal 0 HcmV?d00001 diff --git a/icons/build_game_icons.sh b/icons/build_game_icons.sh index f17a2ad..41dc2c4 100755 --- a/icons/build_game_icons.sh +++ b/icons/build_game_icons.sh @@ -54,6 +54,8 @@ function build_icon_for_skin() { } # Game icons +build_icon ${CURRENT_DIR}/button_back.svg ${BASE_DIR}/assets/icons/button_back.png +build_icon ${CURRENT_DIR}/button_show_conflicts.svg ${BASE_DIR}/assets/icons/button_show_conflicts.png build_icon ${CURRENT_DIR}/button_start.svg ${BASE_DIR}/assets/icons/button_start.png build_icon ${CURRENT_DIR}/difficulty_easy.svg ${BASE_DIR}/assets/icons/difficulty_easy.png build_icon ${CURRENT_DIR}/difficulty_medium.svg ${BASE_DIR}/assets/icons/difficulty_medium.png diff --git a/icons/button_back.svg b/icons/button_back.svg new file mode 100644 index 0000000..0d152c5 --- /dev/null +++ b/icons/button_back.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m46.834 11.248c-19.624 0-35.588 15.964-35.588 35.592 0 19.624 15.964 35.588 35.588 35.588s35.584-15.964 35.584-35.588c0-19.629-15.96-35.592-35.584-35.592zm0 63.607c-15.471 0-28.02-12.544-28.02-28.014 0-15.477 12.549-28.019 28.02-28.019s28.018 12.541 28.018 28.019c0 15.471-12.547 28.014-28.018 28.014z" stroke-width=".75985"/><path d="m55.403 64.285c0.85468 0.85879 3.0403 0.85879 3.0403 0v-34.893c0-0.85985-2.1908-0.85985-3.0486 0l-28.641 15.895c-0.8578 0.85468-0.87224 2.2454-0.0165 3.1032z" fill="#ed9138" stroke-width="1.031"/></svg> diff --git a/icons/button_show_conflicts.svg b/icons/button_show_conflicts.svg new file mode 100644 index 0000000..dd7ee50 --- /dev/null +++ b/icons/button_show_conflicts.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 91.389 91.821" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="91.389" height="91.821" ry="0" fill="#e2b300"/><path d="m79.855 13.662a1.4083 1.4083 0 0 0-1.8775-0.11982l-26.365 20.293-1.1585-12.723a1.4009 1.4009 0 0 0-1.0985-1.2583 1.4367 1.4367 0 0 0-1.558 0.65904l-6.8708 11.644-9.6071-9.5472a1.4562 1.4562 0 0 0-1.6578-0.25965 1.4737 1.4737 0 0 0-0.77887 1.2782 0.972 0.972 0 0 0 0.02006 0.23979l2.177 13.182-21.052-3.4553a1.4314 1.4314 0 0 0-0.99866 2.6166l17.576 11.345-10.825 7.6299a1.4314 1.4314 0 0 0 0.81885 2.5965l12.783 0.13983-13.981 21.751a1.4236 1.4236 0 0 0 2.0972 1.8775l22.23-17.956 5.5725 6.4713a1.4509 1.4509 0 0 0 1.3582 0.45946 1.3606 1.3606 0 0 0 1.0786-0.9588l2.3967-7.1703 12.483 5.7723a1.4376 1.4376 0 0 0 1.6579-0.31951 1.451 1.451 0 0 0 0.19979-1.6777l-6.6512-11.784 13.062-3.5353a1.4274 1.4274 0 0 0 1.0586-1.3182 1.4045 1.4045 0 0 0-0.91882-1.3983l-12.583-4.7337 21.531-27.863a1.4082 1.4082 0 0 0-0.11982-1.8775z" stroke-width="2.0684"/></svg> diff --git a/lib/entities/cell.dart b/lib/entities/cell.dart index 89ea653..369a5f7 100644 --- a/lib/entities/cell.dart +++ b/lib/entities/cell.dart @@ -8,6 +8,7 @@ class Cell { final int col; final int row; bool isFixed; + int conflictsCount = 0; Cell( @required this.value, @@ -28,7 +29,7 @@ class Cell { Color borderDarkColor = Colors.black; Color borderLightColor = Colors.grey; Color borderSelectedColor = Colors.red; - Color backgroundColor = this.isFixed ? Colors.grey[300] : Colors.grey[100]; + Color backgroundColor = this.getBackgroundColor(myProvider); Border borders = Border( top: BorderSide(width: borderWidth, color: ((this.row % size) == 0) ? borderDarkColor : borderLightColor), @@ -67,6 +68,29 @@ class Cell { ); } + Color getBackgroundColor(Data myProvider) { + Color editableCellColor = Colors.grey[100]; + Color editableCellColorConflict = Colors.pink[100]; + Color fixedCellColor = Colors.grey[300]; + Color fixedCellColorConflict = Colors.pink[200]; + + Color backgroundColor = editableCellColor; + + if (this.isFixed) { + backgroundColor = fixedCellColor; + } + + if (myProvider.showConflicts && (this.conflictsCount != 0)) { + if (this.isFixed) { + backgroundColor = fixedCellColorConflict; + } else { + backgroundColor = editableCellColorConflict; + } + } + + return backgroundColor; + } + Container widgetUpdateValue(Data myProvider) { String imageAsset = 'assets/skins/empty.png'; if (this.value > 0) { diff --git a/lib/provider/data.dart b/lib/provider/data.dart index fd49afc..ea939bf 100644 --- a/lib/provider/data.dart +++ b/lib/provider/data.dart @@ -15,6 +15,7 @@ class Data extends ChangeNotifier { String _level = 'medium'; int _size = 3; String _skin = 'default'; + bool _showConflicts = false; // Game data bool _stateRunning = false; @@ -40,6 +41,12 @@ class Data extends ChangeNotifier { notifyListeners(); } + bool get showConflicts => _showConflicts; + set updateShowConflicts(bool showConflicts) { + _showConflicts = showConflicts; + notifyListeners(); + } + getParameterValue(String parameterCode) { switch(parameterCode) { case 'difficulty': { return _level; } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 74b014b..ce75433 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -318,45 +318,65 @@ class Home extends StatelessWidget { bool _checkBoardIsSolved(Data myProvider) { List cells = myProvider.cells; int size = myProvider.size; + int sideLength = pow(size, 2); + + bool isSolved = true; + + // reset conflict states + for (var row = 0; row < sideLength; row++) { + for (var col = 0; col < sideLength; col++) { + cells[row][col].conflictsCount = 0; + } + } // check grid is fully completed - for (var row = 0; row < pow(size, 2); row++) { - for (var col = 0; col < pow(size, 2); col++) { + for (var row = 0; row < sideLength; row++) { + for (var col = 0; col < sideLength; col++) { if (cells[row][col].value == 0) { - print('grid not complete'); - return false; + isSolved = false; } } } - print('ok grid complete'); // check lines does not contains a value twice - for (var row = 0; row < pow(size, 2); row++) { + for (var row = 0; row < sideLength; row++) { List values = []; - for (var col = 0; col < pow(size, 2); col++) { - values.add(cells[row][col].value); + for (var col = 0; col < sideLength; col++) { + int value = cells[row][col].value; + if (value != 0) { + values.add(value); + } } List distinctValues = values.toSet().toList(); if (values.length != distinctValues.length) { print('line ' + row.toString() + ' contains duplicates'); - return false; + // Add line to cells in conflict + for (var col = 0; col < sideLength; col++) { + cells[row][col].conflictsCount++; + } + isSolved = false; } } - print('ok no line with duplicates'); // check columns does not contains a value twice - for (var col = 0; col < pow(size, 2); col++) { + for (var col = 0; col < sideLength; col++) { List values = []; - for (var row = 0; row < pow(size, 2); row++) { - values.add(cells[row][col].value); + for (var row = 0; row < sideLength; row++) { + int value = cells[row][col].value; + if (value != 0) { + values.add(value); + } } List distinctValues = values.toSet().toList(); if (values.length != distinctValues.length) { print('column ' + col.toString() + ' contains duplicates'); - return false; + // Add column to cells in conflict + for (var row = 0; row < sideLength; row++) { + cells[row][col].conflictsCount++; + } + isSolved = false; } } - print('ok no column with duplicates'); // check blocks does not contains a value twice for (var blockRow = 0; blockRow < size; blockRow++) { @@ -367,37 +387,78 @@ class Home extends StatelessWidget { for (var colInBlock = 0; colInBlock < size; colInBlock++) { int row = (blockRow * size) + rowInBlock; int col = (blockCol * size) + colInBlock; - values.add(cells[row][col].value); + int value = cells[row][col].value; + if (value != 0) { + values.add(value); + } } } List distinctValues = values.toSet().toList(); if (values.length != distinctValues.length) { print('block [' + blockCol.toString() + ',' + blockRow.toString() + '] contains duplicates'); - return false; + // Add blocks to cells in conflict + for (var rowInBlock = 0; rowInBlock < size; rowInBlock++) { + for (var colInBlock = 0; colInBlock < size; colInBlock++) { + int row = (blockRow * size) + rowInBlock; + int col = (blockCol * size) + colInBlock; + cells[row][col].conflictsCount++; + } + } + isSolved = false; } } } - print('ok no block with duplicates'); - print('-> ok sudoku solved!'); - return true; + if (isSolved) { + print('-> ok sudoku solved!'); + } + + return isSolved; } @override Widget build(BuildContext context) { Data myProvider = Provider.of<Data>(context); + List<Widget> menuActions = []; + + if (myProvider.stateRunning) { + menuActions.add( + FlatButton( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + border: Border.all( + color: myProvider.showConflicts ? Colors.white : Colors.blue, + width: 4, + ), + ), + margin: EdgeInsets.all(8), + child: Image( + image: AssetImage('assets/icons/button_show_conflicts.png'), + fit: BoxFit.fill + ), + ), + onPressed: () { myProvider.updateShowConflicts = !myProvider.showConflicts; }, + ) + ); + + menuActions.add( + FlatButton( + child: Image( + image: AssetImage('assets/icons/button_back.png'), + fit: BoxFit.fill + ), + onPressed: () => resetGame(myProvider), + ), + ); + } + return Scaffold( appBar: AppBar( title: Text('🔢'), - actions: [ - if (myProvider.stateRunning) - FlatButton( - child: Text('◀️'), - onPressed: () => resetGame(myProvider), - ), - ], + actions: menuActions, ), body: SafeArea( child: Center( -- GitLab