1616
1717package org .microg .tools .ui ;
1818
19+ import android .content .Intent ;
20+ import android .graphics .drawable .Drawable ;
1921import android .os .Bundle ;
20- import android .view .MotionEvent ;
21- import android .util .Log ;
22+ import android .text .Html ;
2223import android .view .LayoutInflater ;
2324import android .view .View ;
2425import android .view .ViewGroup ;
25- import android .widget .CheckBox ;
26+ import android .widget .ImageView ;
2627import android .widget .TextView ;
2728
29+ import androidx .activity .result .ActivityResultLauncher ;
30+ import androidx .activity .result .contract .ActivityResultContracts ;
2831import androidx .annotation .Nullable ;
2932import androidx .fragment .app .Fragment ;
3033
34+ import com .google .android .material .chip .Chip ;
35+ import com .google .android .material .chip .ChipGroup ;
36+ import com .google .android .material .transition .platform .MaterialSharedAxis ;
37+
3138import org .microg .tools .selfcheck .SelfCheckGroup ;
3239
3340import java .util .ArrayList ;
3441import java .util .List ;
3542
3643import static android .view .View .GONE ;
44+ import static android .view .View .VISIBLE ;
3745import static android .view .View .INVISIBLE ;
3846import static org .microg .tools .selfcheck .SelfCheckGroup .Result .Negative ;
3947import static org .microg .tools .selfcheck .SelfCheckGroup .Result .Positive ;
4048import static org .microg .tools .selfcheck .SelfCheckGroup .Result .Unknown ;
4149
4250public abstract class AbstractSelfCheckFragment extends Fragment {
43- private static final String TAG = "SelfCheck" ;
44-
4551 private ViewGroup root ;
52+ protected ActivityResultLauncher <Intent > resolutionLauncher ;
53+ protected ActivityResultLauncher <String []> permissionsLauncher ;
54+
55+ public static class ChipInfo {
56+ public String label ;
57+ public Drawable icon ;
58+ public View .OnClickListener onClick ;
59+
60+ public ChipInfo (String label , Drawable icon , View .OnClickListener onClick ) {
61+ this .label = label ;
62+ this .icon = icon ;
63+ this .onClick = onClick ;
64+ }
65+ }
66+
67+ @ Override
68+ public void onCreate (Bundle savedInstanceState ) {
69+ super .onCreate (savedInstanceState );
70+ resolutionLauncher = registerForActivityResult (new ActivityResultContracts .StartActivityForResult (), r -> reset (LayoutInflater .from (getContext ())));
71+ permissionsLauncher = registerForActivityResult (new ActivityResultContracts .RequestMultiplePermissions (), r -> reset (LayoutInflater .from (getContext ())));
72+
73+ setEnterTransition (new MaterialSharedAxis (MaterialSharedAxis .X , true ));
74+ setExitTransition (new MaterialSharedAxis (MaterialSharedAxis .X , true ));
75+ }
76+
77+ public void launchIntent (Intent intent ) {
78+ resolutionLauncher .launch (intent );
79+ }
4680
4781 @ Nullable
4882 @ Override
4983 public View onCreateView (LayoutInflater inflater , ViewGroup container , Bundle savedInstanceState ) {
50- View scrollRoot = inflater .inflate (R .layout .self_check , container , false );
51- root = scrollRoot .findViewById (R .id .self_check_root );
84+ View scrollRoot = inflater .inflate (org . microg . tools . ui . R .layout .self_check , container , false );
85+ root = scrollRoot .findViewById (org . microg . tools . ui . R .id .self_check_root );
5286 reset (inflater );
5387 return scrollRoot ;
5488 }
5589
5690 protected abstract void prepareSelfCheckList (List <SelfCheckGroup > checks );
5791
5892 protected void reset (LayoutInflater inflater ) {
93+ if (root == null ) return ;
5994 List <SelfCheckGroup > selfCheckGroupList = new ArrayList <>();
6095 prepareSelfCheckList (selfCheckGroupList );
61-
6296 root .removeAllViews ();
6397 for (SelfCheckGroup group : selfCheckGroupList ) {
64- View groupView = inflater .inflate (R .layout .self_check_group , root , false );
98+ View groupView = inflater .inflate (org . microg . tools . ui . R .layout .self_check_group , root , false );
6599 ((TextView ) groupView .findViewById (android .R .id .title )).setText (group .getGroupName (getContext ()));
66- final ViewGroup viewGroup = groupView .findViewById (R .id .group_content );
67- final SelfCheckGroup .ResultCollector collector = new GroupResultCollector (viewGroup );
68- try {
69- group .doChecks (getContext (), collector );
70- } catch (Exception e ) {
71- Log .w (TAG , "Failed during check " + group .getGroupName (getContext ()), e );
72- collector .addResult ("Self-check failed:" , Negative , "An exception occurred during self-check. Please report this issue." );
73- }
100+ final ViewGroup viewGroup = groupView .findViewById (org .microg .tools .ui .R .id .group_content );
101+ group .doChecks (getContext (), new GroupResultCollector (viewGroup ));
74102 root .addView (groupView );
75103 }
76104 }
@@ -83,56 +111,80 @@ public GroupResultCollector(ViewGroup viewGroup) {
83111 }
84112
85113 @ Override
86- public void addResult (final String name , final SelfCheckGroup .Result result , final String resolution ) {
87- addResult (name , result , resolution , null );
114+ public void addResult (String name , SelfCheckGroup .Result result , String resolution ) {
115+ addResult (name , result , resolution , true , null , null );
88116 }
89117
90118 @ Override
91- public void addResult (final String name , final SelfCheckGroup .Result result , final String resolution , final SelfCheckGroup .CheckResolver resolver ) {
92- if (result == null || getActivity () == null ) return ;
93- getActivity ().runOnUiThread (() -> {
94- View resultEntry = LayoutInflater .from (getContext ()).inflate (R .layout .self_check_entry , viewGroup , false );
119+ public void addResult (String name , SelfCheckGroup .Result result , String resolution , SelfCheckGroup .CheckResolver resolver ) {
120+ addResult (name , result , resolution , true , null , resolver );
121+ }
95122
96- TextView nameView = resultEntry .findViewById (R .id .self_check_name );
97- TextView resolutionView = resultEntry .findViewById (R .id .self_check_resolution );
98- CheckBox checkBox = resultEntry .findViewById (R .id .self_check_result );
99- resultEntry .findViewById (R .id .list_item_check );
123+ @ Override
124+ public void addResult (String name , SelfCheckGroup .Result result , String resolution , boolean showIcon , List <ChipInfo > chips , SelfCheckGroup .CheckResolver resolver ) {
125+ if (getActivity () == null || getContext () == null ) return ;
126+ getActivity ().runOnUiThread (() -> {
127+ View entry = LayoutInflater .from (getContext ()).inflate (org .microg .tools .ui .R .layout .self_check_entry , viewGroup , false );
128+ TextView nameView = entry .findViewById (org .microg .tools .ui .R .id .self_check_name );
129+ TextView resView = entry .findViewById (org .microg .tools .ui .R .id .self_check_resolution );
130+ ImageView resultIcon = entry .findViewById (org .microg .tools .ui .R .id .self_check_result_icon );
131+ ChipGroup chipGroup = entry .findViewById (org .microg .tools .ui .R .id .self_check_chip_group );
100132
101133 nameView .setText (name );
102134
103- resultEntry .findViewById (R .id .self_check_result ).setOnTouchListener ((v , event ) -> {
104- if (event .getAction () == MotionEvent .ACTION_UP ) {
105- if (event .getX () >= 0 && event .getX () <= v .getWidth () && event .getY () >= 0 && event .getY () <= v .getHeight ()) {
106- v .performClick ();
107- }
135+ if (showIcon ) {
136+ resultIcon .setVisibility (VISIBLE );
137+ if (result == Positive ) {
138+ resultIcon .setActivated (true );
139+ } else if (result == Negative ) {
140+ resultIcon .setActivated (false );
141+ } else {
142+ resultIcon .setVisibility (INVISIBLE );
108143 }
109- return true ;
110- });
144+ } else {
145+ resultIcon .setVisibility (GONE );
146+ }
111147
112148 if (result == Positive ) {
113- checkBox .setChecked (true );
114- resolutionView .setVisibility (GONE );
149+ resView .setVisibility (GONE );
115150 } else {
116- resolutionView .setText (resolution );
117- if (result == Unknown ) {
118- checkBox .setVisibility (INVISIBLE );
119- }
151+ resView .setVisibility (VISIBLE );
152+ resView .setText (Html .fromHtml (resolution , Html .FROM_HTML_MODE_COMPACT ));
120153 if (resolver != null ) {
121- resultEntry .setClickable (true );
122- resultEntry .setOnClickListener (v -> resolver .tryResolve (AbstractSelfCheckFragment .this ));
154+ entry .setClickable (true );
155+ entry .setOnClickListener (v -> resolver .tryResolve (AbstractSelfCheckFragment .this ));
123156 }
124157 }
125158
126- viewGroup .addView (resultEntry );
127-
128- for (int i = 0 ; i < viewGroup .getChildCount (); i ++) {
129- View child = viewGroup .getChildAt (i );
130- com .google .android .material .listitem .ListItemLayout layout = child .findViewById (R .id .list_item_check );
131- if (layout != null ) {
132- layout .updateAppearance (i , viewGroup .getChildCount ());
159+ if (chips != null && !chips .isEmpty ()) {
160+ chipGroup .setVisibility (VISIBLE );
161+ chipGroup .removeAllViews ();
162+ for (ChipInfo info : chips ) {
163+ Chip chip = (Chip ) LayoutInflater .from (getContext ()).inflate (org .microg .tools .ui .R .layout .self_check_chip , chipGroup , false );
164+ chip .setText (info .label );
165+ if (info .icon != null ) {
166+ chip .setChipIcon (info .icon );
167+ chip .setChipIconVisible (true );
168+ }
169+ if (info .onClick != null ) {
170+ chip .setOnClickListener (info .onClick );
171+ }
172+ chipGroup .addView (chip );
133173 }
134174 }
175+
176+ viewGroup .addView (entry );
177+ updateSegmentedStyle ();
135178 });
136179 }
180+
181+ private void updateSegmentedStyle () {
182+ for (int i = 0 ; i < viewGroup .getChildCount (); i ++) {
183+ View child = viewGroup .getChildAt (i );
184+ if (child instanceof com .google .android .material .listitem .ListItemLayout ) {
185+ ((com .google .android .material .listitem .ListItemLayout ) child ).updateAppearance (i , viewGroup .getChildCount ());
186+ }
187+ }
188+ }
137189 }
138190}
0 commit comments