Project

General

Profile

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

magiccube / src / main / java / org / distorted / main / MainActivity.java @ e9245b7b

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.main_old.RubikSurfaceView;
47
import org.distorted.messaging.RubikInAppMessanging;
48
import org.distorted.objectlib.main.ObjectControl;
49
import org.distorted.objects.RubikObjectList;
50
import org.distorted.patternui.PatternActivity;
51
import org.distorted.solverui.SolverActivity;
52
import org.distorted.tutorials.TutorialActivity;
53

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

    
56
public class MainActivity extends AppCompatActivity implements RubikNetwork.Updatee
57
{
58
    public static final float RATIO_BAR = 0.080f;
59
    public static final int FLAGS =  View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
60
                                   | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
61
                                   | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
62
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
63
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
64

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

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

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

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

    
87
      cutoutHack();
88
      computeHeights();
89

    
90
      mCurrVersion = getAppVers();
91

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

    
101
      thread.start();
102
      }
103

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

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

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

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

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

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

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

    
132
        decorView.setSystemUiVisibility(FLAGS);
133

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

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

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

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

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

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

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

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178
// do not avoid cutouts
179

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

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

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

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

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

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

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

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

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

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

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

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

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

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

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

    
250
      if( mJustStarted )
251
        {
252
        mJustStarted = false;
253
        RubikScores scores = RubikScores.getInstance();
254
        scores.incrementNumRuns();
255
        scores.setCountry(this);
256
        RubikObjectList.restoreMeshState(preferences);
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
      RubikObjectList.saveMeshState(editor);
307

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

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

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

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

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

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

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

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

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
// PUBLIC API
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

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

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

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

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

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

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

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

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

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

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

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

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

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

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

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

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

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

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

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

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

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

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

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

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

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

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

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

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

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