Project

General

Profile

Download (16.2 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / main / MainActivity.java @ 337f4660

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.main;
11

    
12
import android.content.Intent;
13
import android.content.SharedPreferences;
14
import android.content.pm.PackageInfo;
15
import android.content.pm.PackageManager;
16
import android.content.res.Configuration;
17
import android.os.Build;
18
import android.os.Bundle;
19
import android.util.DisplayMetrics;
20
import android.util.TypedValue;
21
import android.view.DisplayCutout;
22
import android.view.View;
23
import android.view.ViewGroup;
24
import android.view.WindowManager;
25
import android.widget.LinearLayout;
26
import android.widget.ScrollView;
27
import android.widget.TextView;
28

    
29
import androidx.annotation.NonNull;
30
import androidx.appcompat.app.AppCompatActivity;
31
import androidx.preference.PreferenceManager;
32

    
33
import com.google.firebase.analytics.FirebaseAnalytics;
34
import com.google.firebase.inappmessaging.FirebaseInAppMessaging;
35

    
36
import org.distorted.bandaged.BandagedCreatorActivity;
37
import org.distorted.config.ConfigActivity;
38
import org.distorted.dialogs.RubikDialogAbout;
39
import org.distorted.dialogs.RubikDialogCreators;
40
import org.distorted.dialogs.RubikDialogExit;
41
import org.distorted.dialogs.RubikDialogScores;
42
import org.distorted.dialogs.RubikDialogUpdates;
43
import org.distorted.external.RubikNetwork;
44
import org.distorted.external.RubikScores;
45
import org.distorted.external.RubikUpdates;
46
import org.distorted.messaging.RubikInAppMessanging;
47
import org.distorted.objects.RubikObjectList;
48
import org.distorted.patternui.PatternActivity;
49
import org.distorted.solverui.SolverActivity;
50
import org.distorted.tutorials.TutorialActivity;
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

    
54
public class MainActivity extends AppCompatActivity implements RubikNetwork.Updatee
55
{
56
    public static final float PATTERN_CHILD_TEXT  = 0.038f;
57
    public static final float PATTERN_GROUP_TEXT  = 0.060f;
58

    
59
    public static final float RATIO_BAR = 0.080f;
60
    public static final int FLAGS =  View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
61
                                   | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
62
                                   | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
63
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
64
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
65

    
66
    private boolean mJustStarted;
67
    private FirebaseAnalytics mFirebaseAnalytics;
68
    private int mCurrentApiVersion;
69
    private String mOldVersion, mCurrVersion;
70
    private int mScreenWidth;
71
    private TextView mBubbleUpdates;
72
    private int mNumUpdates;
73
    private MainScrollGrid mGrid;
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
    @Override
78
    protected void onCreate(Bundle savedState)
79
      {
80
      super.onCreate(savedState);
81
      setTheme(R.style.MaterialThemeNoActionBar);
82
      setContentView(R.layout.main);
83
      hideNavigationBar();
84

    
85
      mJustStarted = true;
86
      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
87

    
88
      cutoutHack();
89
      computeHeights();
90

    
91
      mCurrVersion = getAppVers();
92

    
93
      Thread thread = new Thread()
94
        {
95
        public void run()
96
          {
97
          RubikInAppMessanging listener = new RubikInAppMessanging();
98
          FirebaseInAppMessaging.getInstance().addClickListener(listener);
99
          }
100
        };
101

    
102
      thread.start();
103
      }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106
// this does not include possible insets
107

    
108
    private void computeHeights()
109
      {
110
      LinearLayout.LayoutParams pU = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, RATIO_BAR);
111
      LinearLayout layoutTop = findViewById(R.id.upperBar);
112
      layoutTop.setLayoutParams(pU);
113

    
114
      LinearLayout.LayoutParams pS = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1-2*RATIO_BAR);
115
      ScrollView scroll = findViewById(R.id.objectScroll);
116
      scroll.setLayoutParams(pS);
117

    
118
      LinearLayout.LayoutParams pL = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, RATIO_BAR);
119
      LinearLayout layoutBot = findViewById(R.id.lowerBar);
120
      layoutBot.setLayoutParams(pL);
121
      }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
    private void hideNavigationBar()
126
      {
127
      mCurrentApiVersion = Build.VERSION.SDK_INT;
128

    
129
      if(mCurrentApiVersion >= Build.VERSION_CODES.KITKAT)
130
        {
131
        final View decorView = getWindow().getDecorView();
132

    
133
        decorView.setSystemUiVisibility(FLAGS);
134

    
135
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
136
          {
137
          @Override
138
          public void onSystemUiVisibilityChange(int visibility)
139
            {
140
            if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
141
              {
142
              decorView.setSystemUiVisibility(FLAGS);
143
              }
144
            }
145
          });
146
        }
147
      }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
    @Override
152
    public void onAttachedToWindow()
153
      {
154
      super.onAttachedToWindow();
155

    
156
      getWindowWidth(getResources().getConfiguration());
157
      mGrid = new MainScrollGrid();
158
      mGrid.createGrid(this,mScreenWidth);
159

    
160
      if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.P )
161
        {
162
        DisplayCutout cutout = getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
163
        int insetHeight = cutout!=null ? cutout.getSafeInsetTop() : 0;
164

    
165
        if( insetHeight>0 )
166
          {
167
          LinearLayout.LayoutParams pH = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, RATIO_BAR);
168
          LinearLayout layoutHid = findViewById(R.id.hiddenBar);
169
          layoutHid.setLayoutParams(pH);
170

    
171
          LinearLayout.LayoutParams pS = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1-3*RATIO_BAR);
172
          ScrollView scroll = findViewById(R.id.objectScroll);
173
          scroll.setLayoutParams(pS);
174
          }
175
        }
176
      }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
// do not avoid cutouts
180

    
181
    private void cutoutHack()
182
      {
183
      if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.P )
184
        {
185
        getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
186
        }
187
      }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

    
191
    private void getWindowWidth(Configuration conf)
192
      {
193
      int dpi = getResources().getDisplayMetrics().densityDpi;
194
      float conv = ((float) dpi/DisplayMetrics.DENSITY_DEFAULT);
195

    
196
      mScreenWidth = (int) (conf.screenWidthDp*conv + 0.5f);
197
      }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
    @Override
202
    public void onWindowFocusChanged(boolean hasFocus)
203
      {
204
      super.onWindowFocusChanged(hasFocus);
205

    
206
      if( mCurrentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus )
207
        {
208
        getWindow().getDecorView().setSystemUiVisibility(FLAGS);
209
        }
210
      }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
    @Override
215
    public void onConfigurationChanged(@NonNull Configuration conf)
216
      {
217
      super.onConfigurationChanged(conf);
218

    
219
      getWindowWidth(conf);
220
      mGrid.updateGrid(this,mScreenWidth);
221
      }
222

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224
    
225
    @Override
226
    protected void onPause() 
227
      {
228
      super.onPause();
229
      RubikNetwork.onPause();
230
      savePreferences();
231
      }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234
    
235
    @Override
236
    protected void onResume() 
237
      {
238
      super.onResume();
239

    
240
      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
241
      restorePreferences(preferences,mJustStarted);
242

    
243
      mBubbleUpdates = findViewById(R.id.bubbleUpdates);
244
      mBubbleUpdates.setVisibility(View.INVISIBLE);
245
      mNumUpdates = 0;
246

    
247
      RubikNetwork network = RubikNetwork.getInstance();
248
      network.signUpForUpdates(this);
249
      network.downloadUpdates(this);
250

    
251
      if( mJustStarted )
252
        {
253
        mJustStarted = false;
254
        RubikScores scores = RubikScores.getInstance();
255
        scores.incrementNumRuns();
256
        scores.setCountry(this);
257
        }
258

    
259
      if( !mOldVersion.equals(mCurrVersion) ) displayNovelties();
260
      }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

    
264
    private void displayNovelties()
265
      {
266
      Bundle bundle = new Bundle();
267
      bundle.putString("argument",mOldVersion);
268
      RubikDialogAbout newDialog = new RubikDialogAbout();
269
      newDialog.setArguments(bundle);
270
      newDialog.show(getSupportFragmentManager(), RubikDialogAbout.getDialogTag() );
271
      }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
    
275
    @Override
276
    protected void onDestroy() 
277
      {
278
      super.onDestroy();
279
      }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

    
283
    private String getAppVers()
284
      {
285
      try
286
        {
287
        PackageInfo pInfo = getPackageManager().getPackageInfo( getPackageName(), 0);
288
        return pInfo.versionName;
289
        }
290
      catch( PackageManager.NameNotFoundException e )
291
        {
292
        return "unknown";
293
        }
294
      }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
    private void savePreferences()
299
      {
300
      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
301
      SharedPreferences.Editor editor = preferences.edit();
302

    
303
      editor.putString("appVersion", mCurrVersion );
304

    
305
      RubikObjectList.savePreferences(editor);
306

    
307
      boolean success = editor.commit();
308
      if( !success ) android.util.Log.e("D", "Failed to save preferences");
309
      }
310

    
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312

    
313
    private void restorePreferences(SharedPreferences preferences, boolean justStarted)
314
      {
315
      mOldVersion = preferences.getString("appVersion","");
316

    
317
      RubikObjectList.restorePreferences(this,preferences,justStarted);
318
      RubikScores scores = RubikScores.getInstance();
319

    
320
      if( scores.isVerified() )
321
        {
322
        FirebaseAnalytics analytics = getAnalytics();
323
        analytics.setUserId(scores.getName());
324
        }
325
      }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
    private void updateBubble(int num)
330
      {
331
      runOnUiThread(new Runnable()
332
        {
333
        @Override
334
        public void run()
335
          {
336
          mNumUpdates = num;
337

    
338
          if( num>0 )
339
            {
340
            String shownNum = String.valueOf(num);
341
            mBubbleUpdates.setText(shownNum);
342
            mBubbleUpdates.setVisibility(View.VISIBLE);
343
            int height = (int)(0.05f*mScreenWidth);
344
            mBubbleUpdates.setTextSize(TypedValue.COMPLEX_UNIT_PX,height);
345
            }
346
          else
347
            {
348
            mBubbleUpdates.setVisibility(View.INVISIBLE);
349
            }
350
          }
351
        });
352
      }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
// PUBLIC API
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
    public FirebaseAnalytics getAnalytics()
359
      {
360
      return mFirebaseAnalytics;
361
      }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
    public void switchToTutorial(String url, int objectOrdinal)
366
      {
367
      Intent intent = new Intent(this, TutorialActivity.class);
368
      intent.putExtra("url", url);
369
      intent.putExtra("obj", objectOrdinal);
370
      startActivity(intent);
371
      }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
    public void switchToConfig(int objectOrdinal)
376
      {
377
      Intent intent = new Intent(this, ConfigActivity.class);
378
      intent.putExtra("obj", objectOrdinal);
379
      startActivity(intent);
380
      }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
    public void switchToBandagedCreator(int objectOrdinal)
385
      {
386
      Intent intent = new Intent(this, BandagedCreatorActivity.class);
387
      intent.putExtra("obj", objectOrdinal);
388
      startActivity(intent);
389
      }
390

    
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

    
393
    public void switchToSolver(int objectOrdinal)
394
      {
395
      Intent intent = new Intent(this, SolverActivity.class);
396
      intent.putExtra("obj", objectOrdinal);
397
      startActivity(intent);
398
      }
399

    
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

    
402
    public void switchToPattern(int objectOrdinal)
403
      {
404
      Intent intent = new Intent(this, PatternActivity.class);
405
      intent.putExtra("obj", objectOrdinal);
406
      startActivity(intent);
407
      }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410

    
411
    public void onScores(View v)
412
      {
413
      Bundle sBundle = new Bundle();
414
      sBundle.putString("argument", "false");
415
      RubikDialogScores scores = new RubikDialogScores();
416
      scores.setArguments(sBundle);
417
      scores.show(getSupportFragmentManager(), null);
418
      }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
    public void onUpdates(View v)
423
      {
424
      RubikDialogUpdates diag = new RubikDialogUpdates();
425
      diag.show( getSupportFragmentManager(), RubikDialogUpdates.getDialogTag() );
426
      }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
    public void onExit(View v)
431
      {
432
      RubikDialogExit diag = new RubikDialogExit();
433
      diag.show(getSupportFragmentManager(), null);
434
      }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
    public void onAbout(View v)
439
      {
440
      RubikDialogAbout diag = new RubikDialogAbout();
441
      diag.show(getSupportFragmentManager(), null);
442
      }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
    public void onBandage(View v)
447
      {
448
      RubikDialogCreators diag = new RubikDialogCreators();
449
      diag.show(getSupportFragmentManager(), RubikDialogCreators.getDialogTag() );
450
      }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
    public void receiveUpdate(RubikUpdates updates)
455
      {
456
      int num = updates.getCompletedNumber();
457
      updateBubble(num);
458
      }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461

    
462
    public void objectDownloaded(String shortName)
463
      {
464
      mNumUpdates--;
465
      updateBubble(mNumUpdates);
466
      mGrid.updateGrid(this,mScreenWidth);
467
      }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
    public int getType()
472
      {
473
      return 0;
474
      }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
    public void errorUpdate()
479
      {
480
      android.util.Log.e("D", "NewRubikActivity: Error receiving downloaded objects update");
481
      }
482
}
(1-1/3)