diff --git a/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java b/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java index 4213ddc..b2da717 100644 --- a/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java +++ b/app/src/main/java/com/dhangofa/networktoggle/MainActivity.java @@ -192,6 +192,7 @@ protected void onCreate(Bundle savedInstanceState) { bindSelectionListeners(); updateSeparatorVisibility(); setupCarousel(); + setupStaticLandscapeCards(); } private void configureStatusBar() { @@ -247,6 +248,21 @@ private void bindLinks() { } + private void setupStaticLandscapeCards() { + View btn1 = findViewById(R.id.staticCardButton1); + if (btn1 != null) { + btn1.setOnClickListener(v -> openUrl("https://github.com/Dhangofa/NetToggle/wiki/1.-Execution-Mode-Configuration")); + } + View btn2 = findViewById(R.id.staticCardButton2); + if (btn2 != null) { + btn2.setOnClickListener(v -> openUrl("https://github.com/Dhangofa/NetToggle/wiki/2.-Target-SIM-Setup-&-Quick-Tile-Cycle-Guide")); + } + View btn3 = findViewById(R.id.staticCardButton3); + if (btn3 != null) { + btn3.setOnClickListener(v -> openUrl("https://github.com/Dhangofa/NetToggle/wiki/3.-Adding-the-Tile-to-Quick-Settings")); + } + } + private void setupCarousel() { if (carouselBackground == null) return; carouselItems = new CarouselItem[]{ @@ -270,16 +286,17 @@ private void setupCarousel() { case android.view.MotionEvent.ACTION_CANCEL: float deltaX = event.getX() - touchStartX; if (Math.abs(deltaX) > 100) { - carouselHandler.removeCallbacks(carouselAutoRunnable); - if (deltaX > 0 && currentCarouselIndex > 0) { - currentCarouselIndex--; + if (deltaX > 0) { + // Swipe right (previous page) + currentCarouselIndex = (currentCarouselIndex - 1 + carouselItems.length) % carouselItems.length; renderCarouselPage(currentCarouselIndex, true, -1); - } else if (deltaX < 0 && currentCarouselIndex < carouselItems.length - 1) { - currentCarouselIndex++; + } else if (deltaX < 0) { + // Swipe left (next page) + currentCarouselIndex = (currentCarouselIndex + 1) % carouselItems.length; renderCarouselPage(currentCarouselIndex, true, 1); } - // Resume after 10 seconds of inactivity - carouselHandler.postDelayed(carouselAutoRunnable, 10000); + + } else if (event.getAction() == android.view.MotionEvent.ACTION_UP) { v.performClick(); } @@ -343,7 +360,7 @@ private void renderCarouselPage(int index, boolean animate, int direction) { // Prepare for animate in view.setTranslationX(moveInX); - view.animate().translationX(0f).alpha(1f).setDuration(duration) + view.animate().translationX(0f).alpha(1f).setDuration(duration / 2) .setInterpolator(new android.view.animation.DecelerateInterpolator()) .start(); }).start(); @@ -488,22 +505,17 @@ private void bindSelectionListeners() { @Override protected void onResume() { super.onResume(); + if (appPreferences != null) updateAutoSimWarning(); checkAndRequestPermission(); updateErrorBanner(); updateCapabilities(); - if (carouselHandler != null && carouselAutoRunnable != null) { - carouselHandler.removeCallbacks(carouselAutoRunnable); - carouselHandler.postDelayed(carouselAutoRunnable, 5000); - } + } @Override protected void onPause() { super.onPause(); - if (carouselHandler != null && carouselAutoRunnable != null) { - carouselHandler.removeCallbacks(carouselAutoRunnable); - } } private void checkAndRequestPermission() { @@ -733,56 +745,40 @@ private void setStatus(String text, int color) { } - private android.os.Handler carouselHandler = new android.os.Handler(android.os.Looper.getMainLooper()); - private Runnable carouselAutoRunnable = new Runnable() { - @Override - public void run() { - if (carouselItems == null) return; - - int nextIndex; - if (!isUIAuthorized) { - // If unauthorized but user manually swiped away, bring them back to 0 eventually - nextIndex = 0; - } else { - // If authorized, cycle through logically - nextIndex = (currentCarouselIndex == 2) ? 1 : (currentCarouselIndex + 1); - } - - if (nextIndex != currentCarouselIndex) { - int direction = (nextIndex > currentCarouselIndex) ? 1 : -1; - currentCarouselIndex = nextIndex; - renderCarouselPage(currentCarouselIndex, true, direction); - } - carouselHandler.postDelayed(this, 5000); - } - }; + + + + private void updateCarouselContext(boolean authorized) { if (carouselBackground == null || carouselItems == null) return; - carouselHandler.removeCallbacks(carouselAutoRunnable); + + boolean animate = !isFirstCarouselRender; + isFirstCarouselRender = false; if (!authorized) { - if (currentCarouselIndex != 0) { + if (currentCarouselIndex != 0 || !animate) { currentCarouselIndex = 0; - renderCarouselPage(0, true, -1); + renderCarouselPage(0, animate, -1); } - // Will auto-correct to 0 every 5 seconds if user swipes away while unauthorized - carouselHandler.postDelayed(carouselAutoRunnable, 5000); } else { - if (currentCarouselIndex == 0) { + // Always start at 2nd page (index 1) on auth transition + if (currentCarouselIndex != 1 || !animate) { currentCarouselIndex = 1; - renderCarouselPage(1, true, 1); + renderCarouselPage(1, animate, 1); } - carouselHandler.postDelayed(carouselAutoRunnable, 5000); } } private boolean isUIAuthorized = false; + private boolean isFirstCarouselRender = true; + + private void updateAuthorizationUI(boolean authorized) { - updateCarouselContext(authorized); if (isUIAuthorized == authorized) return; isUIAuthorized = authorized; + updateCarouselContext(authorized); float alpha = authorized ? 1.0f : 0.4f; View targetSimCard = findViewById(R.id.targetSimRadioGroup); diff --git a/app/src/main/res/drawable-anydpi-v26/ic_launcher.xml b/app/src/main/res/drawable-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..6b78462 --- /dev/null +++ b/app/src/main/res/drawable-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_launcher.xml b/app/src/main/res/drawable/ic_launcher.xml index 99527c8..e422163 100644 --- a/app/src/main/res/drawable/ic_launcher.xml +++ b/app/src/main/res/drawable/ic_launcher.xml @@ -1,17 +1,48 @@ - - + + + + + + + + + + + + + + + - - + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..da555f4 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 852af25..c7c3207 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -4,10 +4,25 @@ android:height="108dp" android:viewportWidth="108" android:viewportHeight="108"> - + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_logo_ui.xml b/app/src/main/res/drawable/ic_logo_ui.xml new file mode 100644 index 0000000..852af25 --- /dev/null +++ b/app/src/main/res/drawable/ic_logo_ui.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index a556e89..5ccb2ed 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -1,5 +1,6 @@ @@ -174,109 +175,240 @@ android:textColor="@color/text_secondary" android:textSize="12sp" /> - + - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:background="@drawable/shape_pill_badge_bg" + android:backgroundTint="@color/card_surface" + android:gravity="center_vertical" + android:paddingHorizontal="12dp" + android:paddingVertical="6dp" + android:layout_marginTop="12dp" + android:clickable="true" + android:focusable="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8944e11..67f0e0c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@