Skip to content
90 changes: 43 additions & 47 deletions app/src/main/java/com/dhangofa/networktoggle/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ protected void onCreate(Bundle savedInstanceState) {
bindSelectionListeners();
updateSeparatorVisibility();
setupCarousel();
setupStaticLandscapeCards();
}

private void configureStatusBar() {
Expand Down Expand Up @@ -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[]{
Expand All @@ -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();
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/drawable-anydpi-v26/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
45 changes: 38 additions & 7 deletions app/src/main/res/drawable/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">

<!-- Background Circle -->
<!-- Background Circle for legacy icon (Flat blue fallback) -->
<path
android:fillColor="#0066FF"
android:fillColor="#0055FF"
android:pathData="M54,54m-50,0a50,50 0,1 1,100 0a50,50 0,1 1,-100 0" />

<!-- Background Circle with Gradient -->
<path android:pathData="M54,54m-50,0a50,50 0,1 1,100 0a50,50 0,1 1,-100 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="4"
android:startY="4"
android:endX="104"
android:endY="104"
android:type="linear">
<item android:offset="0.0" android:color="#2979FF" /> <!-- Vibrant light blue -->
<item android:offset="0.6" android:color="#0055FF" /> <!-- Standard solid blue -->
<item android:offset="1.0" android:color="#002277" /> <!-- Deep navy edge -->
</gradient>
</aapt:attr>
</path>

<!-- Foreground Group -->
<group
android:translateX="0.0"
android:translateY="0.0">

<!-- Stylized Cell Tower & Signal Waves -->
<path
android:fillColor="#FFFFFF"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z" />
<!-- Subtle Drop Shadow to create floating depth -->
<group android:translateX="2.5" android:translateY="4.5">
<path
android:fillColor="#40001030"
android:fillType="nonZero"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z" />
</group>

<!-- Main Crisp White Icon -->
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z" />
</group>
</vector>
22 changes: 22 additions & 0 deletions app/src/main/res/drawable/ic_launcher_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M0,0h108v108h-108z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="0"
android:startY="0"
android:endX="108"
android:endY="108"
android:type="linear">
<item android:offset="0.0" android:color="#2979FF" /> <!-- Vibrant light blue -->
<item android:offset="0.6" android:color="#0055FF" /> <!-- Standard solid blue -->
<item android:offset="1.0" android:color="#002277" /> <!-- Deep navy edge -->
</gradient>
</aapt:attr>
</path>
</vector>
27 changes: 21 additions & 6 deletions app/src/main/res/drawable/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,25 @@
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />

<group
android:pivotX="54"
android:pivotY="54"
android:scaleX="0.75"
android:scaleY="0.75">

<!-- Subtle Drop Shadow to create floating depth -->
<group android:translateX="2.5" android:translateY="4.5">
<path
android:fillColor="#40001030"
android:fillType="nonZero"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z" />
</group>

<!-- Main Crisp White Icon -->
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z" />
</group>
</vector>
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_logo_ui.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M54,28 A2,2 0 0,0 52,30 L52,42 L42,42 A2,2 0 0,0 40,44 L40,78 A2,2 0 0,0 42,80 L66,80 A2,2 0 0,0 68,78 L68,44 A2,2 0 0,0 66,42 L56,42 L56,30 A2,2 0 0,0 54,28 Z M45,47 L63,47 L63,75 L45,75 Z M32,46 A2,2 0 0,0 30,48 C30,58 34,68 40,75 A2,2 0 0,0 43,72 C37,66 34,58 34,48 A2,2 0 0,0 32,46 Z M76,46 A2,2 0 0,0 74,48 C74,58 71,66 65,72 A2,2 0 0,0 68,75 C74,68 78,58 78,48 A2,2 0 0,0 76,46 Z M23,36 A2,2 0 0,0 21,38 C21,52 26,65 35,76 A2,2 0 0,0 38,73 C29,63 25,51 25,38 A2,2 0 0,0 23,36 Z M85,36 A2,2 0 0,0 83,38 C83,51 79,63 70,73 A2,2 0 0,0 73,76 C82,65 87,52 87,38 A2,2 0 0,0 85,36 Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
Loading