diff --git a/.gitignore b/.gitignore index 246a974..dfff3a7 100644 --- a/.gitignore +++ b/.gitignore @@ -316,3 +316,6 @@ obj/ !/gradle/wrapper/gradle-wrapper.jar # End of https://www.toptal.com/developers/gitignore/api/android,androidstudio,java,kotlin,intellij + +*.png +framescr*.webp \ No newline at end of file diff --git a/app/src/main/kotlin/ui/main/MainScreen.kt b/app/src/main/kotlin/ui/main/MainScreen.kt index b2467fd..171f4fa 100644 --- a/app/src/main/kotlin/ui/main/MainScreen.kt +++ b/app/src/main/kotlin/ui/main/MainScreen.kt @@ -46,6 +46,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult @@ -157,6 +158,7 @@ fun MainScreen( val snackbarResult = snackbarState.showSnackbar( message = snackbarMessage, actionLabel = snackbarActionLabel, + duration = SnackbarDuration.Short, ) if (snackbarResult == SnackbarResult.ActionPerformed) { setShowElevatorAlertsPref(true) @@ -181,6 +183,7 @@ fun MainScreen( val snackbarResult = snackbarState.showSnackbar( message = snackbarMessage, actionLabel = snackbarActionLabel, + duration = SnackbarDuration.Short, ) if (snackbarResult == SnackbarResult.ActionPerformed) { setShowHelpGuidePref(true) diff --git a/app/src/main/kotlin/ui/stations/DirectionWarning.kt b/app/src/main/kotlin/ui/stations/DirectionWarning.kt index 2c06851..5ff388b 100644 --- a/app/src/main/kotlin/ui/stations/DirectionWarning.kt +++ b/app/src/main/kotlin/ui/stations/DirectionWarning.kt @@ -15,6 +15,7 @@ import androidx.compose.material.icons.filled.Info import androidx.compose.material3.ElevatedCard import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text @@ -107,6 +108,7 @@ fun DirectionWarning( val snackbarResult = snackbarState.showSnackbar( message = snackbarMessage, actionLabel = snackbarActionLabel, + duration = SnackbarDuration.Short, ) if (snackbarResult == SnackbarResult.ActionPerformed) { setShowDirectionWarning(true) diff --git a/app/src/test/kotlin/ca/amandeep/path/ui/main/MainScreenshotTest.kt b/app/src/test/kotlin/ca/amandeep/path/ui/main/MainScreenshotTest.kt index f4ebc71..e963e27 100644 --- a/app/src/test/kotlin/ca/amandeep/path/ui/main/MainScreenshotTest.kt +++ b/app/src/test/kotlin/ca/amandeep/path/ui/main/MainScreenshotTest.kt @@ -275,6 +275,7 @@ class MainScreenshotTest( direction = Direction.ToNJ, minsToArrival = 4, alerts = (alertsData().alerts.getOrNull(0) as? AlertData.Grouped)?.let { persistentListOf(it) } ?: persistentListOf(), + forceAlertsOpen = alertsExpanded == true, ), mockTrain( route = Route.HOB_WTC, diff --git a/app/src/test/kotlin/ca/amandeep/path/ui/main/StatusBarLikeBar.kt b/app/src/test/kotlin/ca/amandeep/path/ui/main/StatusBarLikeBar.kt index 4fff84f..bbc15fd 100644 --- a/app/src/test/kotlin/ca/amandeep/path/ui/main/StatusBarLikeBar.kt +++ b/app/src/test/kotlin/ca/amandeep/path/ui/main/StatusBarLikeBar.kt @@ -27,8 +27,9 @@ fun StatusBar( modifier: Modifier = Modifier, includeNotifs: Boolean = false, ) { - val height = 24 - val dpTpSp = 0.5f + val height = 36 + val dpTpSp = 0.55f + val paddingRatio = 0.3f Box( modifier = modifier @@ -38,7 +39,7 @@ fun StatusBar( Row( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 25.dp, vertical = 5.dp), + .padding(horizontal = 25.dp, vertical = (height * paddingRatio).dp), verticalAlignment = Alignment.CenterVertically, ) { Text( @@ -47,7 +48,7 @@ fun StatusBar( .padding(end = 5.dp), text = "2:28", color = MaterialTheme.colorScheme.onBackground, - fontSize = (height * dpTpSp).sp, + fontSize = (height * (1 - paddingRatio) * dpTpSp).sp, ) if (includeNotifs) { Icon( @@ -85,7 +86,7 @@ fun StatusBar( modifier = Modifier.wrapContentHeight(align = Alignment.CenterVertically, unbounded = true), text = "82%", color = MaterialTheme.colorScheme.onBackground, - fontSize = (height * dpTpSp).sp, + fontSize = (height * (1 - paddingRatio) * dpTpSp).sp, ) } } diff --git a/build.gradle b/build.gradle index 0ee10b1..dfb0b21 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,6 @@ plugins { id 'de.mannodermaus.android-junit5' apply false id 'app.cash.licensee' apply false id 'app.cash.paparazzi' apply false - id 'com.squareup.wire' apply false } tasks.register('clean') { diff --git a/diagonalCombine.sh b/diagonalCombine.sh new file mode 100755 index 0000000..b565339 --- /dev/null +++ b/diagonalCombine.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +#This script will merge two jpg images into one using imageMagick. +#The final result will be a picture that is split diagonally. +#The diagonal line will start from the top left of the image. +#Both pictures must be of the same size. +#If you do not give the filenames as part of the command line, the default names will be used (Left.jpg and Right.jpg). + +#If command line argument 1 is not provided, the value will default to the variable $LEFT_DEFAULT +LEFT_DEFAULT="Left.jpg"; +LEFT=${1:-$LEFT_DEFAULT}; + +#If command line argument 2 is not provided, the value will default to the variable $Right_DEFAULT +RIGHT_DEFAULT="Right.jpg"; +RIGHT=${2:-$RIGHT_DEFAULT}; + +#The intermediate images we will use must be png to support transparency. +#We remove the extension '.jpg' from the filenames and add the extension '.png'. +LEFT_OUT="${LEFT%.jpg}.Diagonal Down.png"; +RIGHT_OUT="${RIGHT%.jpg}.Diagonal Down.png"; +OUT="DiagonalDown.jpg"; +OUT_PNG="DiagonalDown.png"; + +#Read the width of one of the images; +WIDTH=`identify -format %w "$LEFT"`; +#Read the height of one of the images; +HEIGHT=`identify -format %h "$LEFT"`; + +OFFSET=1; +WIDTH_M=$((WIDTH-OFFSET)); +HEIGHT_M=$((HEIGHT-OFFSET)); + +#We create a transparent triangle on the side of the image we do not want visible. +#A problem that arises here: we create a triangle with no fill, which turns black. Then we fill that area to make it transparent, since the image is a jpg some of the newly created black pixels do not get removed. When merging the two images, this creates a black diagonal line in the middle. +magick "$LEFT" -gravity north -crop "$WIDTH"x"$HEIGHT"+0+0 +repage \ +-draw "polygon 0,0 "$WIDTH","$HEIGHT" "$WIDTH",0 fill none alpha "$WIDTH_M","$OFFSET" floodfill" \ +\( +clone -channel RGBA \) \ +-compose DstOver -composite "$LEFT_OUT"; + +#We create a transparent triangle on the side of the image we do not want visible. +magick "$RIGHT" -gravity north -crop "$WIDTH"x"$HEIGHT"+0+0 +repage \ +-draw "polygon "$WIDTH","$HEIGHT" 0,0 0,"$HEIGHT" fill none alpha "$OFFSET","$HEIGHT_M" floodfill" \ +\( +clone -channel RGBA \) \ +-compose DstOver -composite "$RIGHT_OUT"; + +#We merge the two images together. +composite -blend 50% "$LEFT_OUT" "$RIGHT_OUT" "$OUT"; + +#Cleaning up +rm "$LEFT_OUT" "$RIGHT_OUT"; +convert -define webp:lossless=true -quality 50 "$OUT" "$OUT_PNG" +rm $OUT \ No newline at end of file diff --git a/frame.webp b/frame.webp new file mode 100644 index 0000000..ac9d576 Binary files /dev/null and b/frame.webp differ diff --git a/frame.xcf b/frame.xcf new file mode 100644 index 0000000..0c0a1bc Binary files /dev/null and b/frame.xcf differ diff --git a/frame1.webp b/frame1.webp new file mode 100644 index 0000000..233eaf3 Binary files /dev/null and b/frame1.webp differ diff --git a/frame2.webp b/frame2.webp new file mode 100644 index 0000000..8bcbdbd Binary files /dev/null and b/frame2.webp differ diff --git a/frame3.webp b/frame3.webp new file mode 100644 index 0000000..201462b Binary files /dev/null and b/frame3.webp differ diff --git a/frame4.webp b/frame4.webp new file mode 100644 index 0000000..227e9cc Binary files /dev/null and b/frame4.webp differ diff --git a/recordPaparazziDebug.sh b/recordPaparazziDebug.sh index 6bb22a1..f57e6af 100755 --- a/recordPaparazziDebug.sh +++ b/recordPaparazziDebug.sh @@ -1,3 +1,119 @@ #!/usr/bin/env bash -rm -rf app/src/test/snapshots/images ; ./gradlew recordPaparazziDebug && python3 organize_paparazzi_images.py +# Constants +SNAPSHOT_DIR="app/src/test/snapshots/images" +RESULT_PNG="result.png" + +SCREENSHOT_FOLDER="app/src/test/snapshots/images/Pixel 8 Pro" +SCREENSHOT_1="$SCREENSHOT_FOLDER/ca.amandeep.path.ui.main_MainScreenshotTest_screenshotMain[darkMode=true, device=Pixel 8 Pro, alertsExp=null, dirWarn=false, helpGuide=false, showOppoDir=false, showNotifs=true, updatedWhen=0 shortNames=false].png" +SCREENSHOT_2="$SCREENSHOT_FOLDER/ca.amandeep.path.ui.main_MainScreenshotTest_screenshotMain[darkMode=false, device=Pixel 8 Pro, alertsExp=true, dirWarn=false, helpGuide=true, showOppoDir=false, showNotifs=true, updatedWhen=0 shortNames=false].png" +SCREENSHOT_3_1="$SCREENSHOT_FOLDER/ca.amandeep.path.ui.main_MainScreenshotTest_screenshotMain[darkMode=true, device=Pixel 8 Pro, alertsExp=null, dirWarn=false, helpGuide=true, showOppoDir=true, showNotifs=true, updatedWhen=0 shortNames=false].png" +SCREENSHOT_3_2="$SCREENSHOT_FOLDER/ca.amandeep.path.ui.main_MainScreenshotTest_screenshotMain[darkMode=false, device=Pixel 8 Pro, alertsExp=null, dirWarn=false, helpGuide=true, showOppoDir=true, showNotifs=true, updatedWhen=0 shortNames=false].png" +SCREENSHOT_3="DiagonalDown.png" +SCREENSHOT_4="$SCREENSHOT_FOLDER/ca.amandeep.path.ui.main_MainScreenshotTest_screenshotMain[darkMode=true, device=Pixel 8 Pro, alertsExp=false, dirWarn=false, helpGuide=true, showOppoDir=false, showNotifs=true, updatedWhen=0 shortNames=false].png" + +FRAME_1="frame1.webp" +FRAME_2="frame2.webp" +FRAME_3="frame3.webp" +FRAME_4="frame4.webp" +FRAMED_1="framescr1.webp" +FRAMED_2="framescr2.webp" +FRAMED_3="framescr3.webp" +FRAMED_4="framescr4.webp" + +# Function to check if a command exists +command_exists() { + command -v "$1" &>/dev/null +} + +# Verify all required commands are available +for cmd in mogrify convert python3; do + if ! command_exists "$cmd"; then + echo "Error: '$cmd' is not available. Please install it and try again." + exit 1 + fi +done + +echo "Preparing environment..." +rm -rf "$SNAPSHOT_DIR" + +echo "Generating and organizing Paparazzi images..." +if ! ./gradlew recordPaparazziDebug; then + echo "Error during 'recordPaparazziDebug'. Please check your setup." + exit 1 +fi + +if ! python3 organize_paparazzi_images.py; then + echo "Error during 'organize_paparazzi_images.py'. Please check the script." + exit 1 +fi + +echo "Trimming images..." +for f in "$SCREENSHOT_1" "$SCREENSHOT_2" "$SCREENSHOT_3_1" "$SCREENSHOT_3_2" "$SCREENSHOT_4"; do + if ! mogrify -trim +repage "$f"; then + echo "Error trimming $f. Please check the image file and mogrify command." + exit 1 + fi +done + +echo "Diagonalizing image..." +rm -f "$SCREENSHOT_3" +./diagonalCombine.sh "$SCREENSHOT_3_1" "$SCREENSHOT_3_2" + +echo "Framing images..." + +rm -f "$RESULT_PNG" +if ! framer --oxipng-level 6 --pngquant-speed 1 "$FRAME_1" "$SCREENSHOT_1"; then + echo "Error during image optimization. Please check 'framer' command." + exit 1 +fi +rm -f "$FRAMED_1" +if ! convert -define webp:lossless=true -quality 50 "$RESULT_PNG" "$FRAMED_1"; then + echo "Error converting $RESULT_PNG to WebP format. Please check the 'convert' command." + exit 1 +fi +rm -f "$RESULT_PNG" + +rm -f "$RESULT_PNG" +if ! framer --oxipng-level 6 --pngquant-speed 1 "$FRAME_2" "$SCREENSHOT_2"; then + echo "Error during image optimization. Please check 'framer' command." + exit 1 +fi +rm -f "$FRAMED_2" +if ! convert -define webp:lossless=true -quality 100 "$RESULT_PNG" "$FRAMED_2"; then + echo "Error converting $RESULT_PNG to WebP format. Please check the 'convert' command." + exit 1 +fi +rm -f "$RESULT_PNG" + +rm -f "$RESULT_PNG" +if ! framer --oxipng-level 6 --pngquant-speed 1 "$FRAME_3" "$SCREENSHOT_3"; then + echo "Error during image optimization. Please check 'framer' command." + exit 1 +fi +rm -f "$FRAMED_3" +if ! convert -define webp:lossless=true -quality 100 "$RESULT_PNG" "$FRAMED_3"; then + echo "Error converting $RESULT_PNG to WebP format. Please check the 'convert' command." + exit 1 +fi +rm -f "$RESULT_PNG" + +rm -f "$RESULT_PNG" +if ! framer --oxipng-level 6 --pngquant-speed 1 "$FRAME_4" "$SCREENSHOT_4"; then + echo "Error during image optimization. Please check 'framer' command." + exit 1 +fi +rm -f "$FRAMED_4" +if ! convert -define webp:lossless=true -quality 100 "$RESULT_PNG" "$FRAMED_4"; then + echo "Error converting $RESULT_PNG to WebP format. Please check the 'convert' command." + exit 1 +fi +rm -f "$RESULT_PNG" + +rm -f "$SCREENSHOT_3" + +for file in framescr*.webp; do convert "$file" "${file%.webp}.png"; done +echo "Process completed successfully. Output file: $FRAMED_1" +echo "Process completed successfully. Output file: $FRAMED_2" +echo "Process completed successfully. Output file: $FRAMED_3" +echo "Process completed successfully. Output file: $FRAMED_4" diff --git a/versions.properties b/versions.properties index 2ab1c71..74a5132 100644 --- a/versions.properties +++ b/versions.properties @@ -9,18 +9,20 @@ #### #### NOTE: Some versions are filtered by the rejectVersionIf predicate. See the settings.gradle.kts file. -plugin.app.cash.licensee=1.9.0 +plugin.app.cash.licensee=1.9.1 plugin.app.cash.paparazzi=1.3.1-thumbnail-scale-5 - -plugin.com.squareup.wire=4.9.6 +## # available=1.3.2 +## # available=1.3.3 plugin.de.mannodermaus.android-junit5=1.10.0.0 -version.app.cash.licensee=1.9.0 +version.app.cash.licensee=1.9.1 +## unused version.app.cash.paparazzi=1.3.1-thumbnail-scale-5 +## unused version.com.google.api.grpc..proto-google-common-protos=2.33.0 ## unused @@ -34,6 +36,7 @@ version.com.google.devtools.ksp..symbol-processing=1.9.22-1.0.17 plugin.org.jmailen.kotlinter=4.2.0 +## unused version.com.google.protobuf..protobuf-java=3.25.2 ## # available=4.0.0-rc-1 ## # available=4.0.0-rc-2 @@ -42,9 +45,9 @@ version.com.google.protobuf..protobuf-java=3.25.2 version.junit.junit=4.13.2 -version.com.google.truth.extensions..truth-java8-extension=1.4.0 +version.com.google.truth.extensions..truth-java8-extension=1.4.2 -version.com.google.truth..truth=1.4.0 +version.com.google.truth..truth=1.4.2 version.kotlinx.collections.immutable=0.3.7 @@ -88,19 +91,17 @@ version.androidx.core-splashscreen=1.0.1 version.androidx.core=1.12.0 -version.androidx.compose.ui=1.6.1 +version.androidx.compose.ui=1.6.2 version.androidx.compose.material3=1.2.0 -version.androidx.compose.material=1.6.1 - - version.wire=4.9.6 +version.androidx.compose.material=1.6.2 -version.androidx.compose.compiler=1.5.9 +version.androidx.compose.compiler=1.5.10 version.androidx.activity=1.8.2 -plugin.com.google.devtools.ksp=1.9.22-1.0.17 +plugin.com.google.devtools.ksp=1.9.22-1.0.18 ## unused plugin.android=8.2.2