diff --git a/app/build.gradle b/app/build.gradle index 74fa137..1a5bffc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,188 +1,188 @@ plugins { id 'com.google.protobuf' id 'org.jetbrains.kotlin.android' id 'com.android.application' id 'com.google.devtools.ksp' } android { compileSdk 36 namespace "it.reyboz.bustorino" defaultConfig { applicationId "it.reyboz.bustorino" minSdkVersion 24 //noinspection EditedTargetSdkVersion targetSdkVersion 36 buildToolsVersion = '36.0.0' - versionCode 74 - versionName "2.5.1" + versionCode 75 + versionName "2.6.0" vectorDrawables.useSupportLibrary = true multiDexEnabled true javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/assets/schemas/".toString()] } } testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } testOptions { unitTests.returnDefaultValues = true } sourceSets { androidTest.assets.srcDirs += files("$projectDir/assets/schemas/".toString()) } buildTypes { debug { applicationIdSuffix ".debug" versionNameSuffix "-dev" } gitpull{ applicationIdSuffix ".gitdev" versionNameSuffix "-gitdev" } } repositories { mavenCentral() mavenLocal() } dependencies { //new libraries } compileOptions { coreLibraryDesugaringEnabled true } kotlin { jvmToolchain 21 } lint { abortOnError false } androidResources { generateLocaleConfig true } buildFeatures{ buildConfig = true } splits{ abi{ enable true reset() // Specifies a list of ABIs for Gradle to create APKs for. include "x86", "x86_64","armeabi-v7a", "arm64-v8a" universalApk true } } packagingOptions { resources.excludes.add("META-INF/*") } } protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.22.3' } generateProtoTasks { all().each { task -> task.builtins { java { option 'lite' } } } } } ksp { arg("room.schemaLocation", "$projectDir/assets/schemas") } dependencies { coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.5" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation 'androidx.legacy:legacy-support-v4:1.0.0' // Guava implementation for DBUpdateWorker implementation 'com.google.guava:guava:33.5.0-android' implementation 'com.google.android.flexbox:flexbox:3.0.0' implementation "androidx.fragment:fragment-ktx:$fragment_version" implementation "androidx.activity:activity-ktx:$activity_version" implementation "androidx.annotation:annotation:1.9.1" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "androidx.appcompat:appcompat:$appcompat_version" implementation "androidx.appcompat:appcompat-resources:$appcompat_version" implementation "androidx.preference:preference-ktx:$preference_version" implementation "androidx.work:work-runtime:$work_version" implementation "androidx.work:work-runtime-ktx:$work_version" implementation "com.google.android.material:material:1.13.0" implementation 'androidx.constraintlayout:constraintlayout:2.2.1' implementation "androidx.coordinatorlayout:coordinatorlayout:1.3.0" implementation 'org.jsoup:jsoup:1.22.1' implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:2.0.1' implementation 'com.android.volley:volley:1.2.1' //maplibre implementation 'org.maplibre.gl:android-sdk:12.0.1' implementation 'org.maplibre.gl:android-sdk-turf:6.0.1' implementation 'org.maplibre.gl:android-plugin-annotation-v9:3.0.2' // remember to enable maven repo jitpack.io when wanting to use osmbonuspack //implementation 'com.github.MKergall:osmbonuspack:6.9.0' // ACRA implementation "ch.acra:acra-mail:$acra_version" implementation "ch.acra:acra-dialog:$acra_version" // google transit realtime implementation 'com.google.protobuf:protoc:4.34.1' implementation 'com.google.protobuf:protobuf-javalite:4.34.1' // mqtt library //implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' //implementation 'com.github.hannesa2:paho.mqtt.android:4.4' implementation("com.hivemq:hivemq-mqtt-client:1.3.13") implementation(platform("com.hivemq:hivemq-mqtt-client-websocket:1.3.13")) // ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" // Lifecycles only (without ViewModel or LiveData) implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" // Legacy implementation 'androidx.legacy:legacy-support-v4:1.0.0' // Room components implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-ktx:$room_version" ksp "androidx.room:room-compiler:$room_version" //multidex - we need this to build the app implementation "androidx.multidex:multidex:$multidex_version" implementation 'de.siegmar:fastcsv:4.2.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation "androidx.test.ext:junit:1.3.0" androidTestImplementation "androidx.test:core:$androidXTestVersion" androidTestImplementation "androidx.test:runner:$androidXTestVersion" androidTestImplementation "androidx.test:rules:$androidXTestVersion" androidTestImplementation "androidx.room:room-testing:$room_version" } diff --git a/cli/diff-changelog.php b/cli/diff-changelog.php index 3867ce2..f487c99 100755 --- a/cli/diff-changelog.php +++ b/cli/diff-changelog.php @@ -1,316 +1,316 @@ #!/usr/bin/php setConduitToken( CONDUIT_API_TOKEN ); // All the arguments must be Differential IDs $diff_ids = $argv; // Remove the first argument that is just the command name array_shift( $diff_ids ); if( $diff_ids ) { // Get Diff IDs but in numeric form (for API requests) $diff_ids_numeric = []; foreach( $diff_ids as $diff_id ) { $diff_ids_numeric[] = (int)ltrim( $diff_id, 'D' ); } // Start from Diff IDs (numeric) and get Diff PHIDs (string) // https://we.phorge.it/conduit/method/differential.revision.search/ $diff_search_results = $client->callMethodSynchronous( 'differential.revision.search', [ 'constraints' => [ 'ids' => $diff_ids_numeric, ], ] ); foreach( $diff_search_results['data'] as $diff_search_result ) { $diff_phid = $diff_search_result['phid']; $diff_phids[] = $diff_phid; $diff_data_by_phid[ $diff_phid ] = $diff_search_result; } } else { // If no Diff was specified, let's try guessing them, but that is a long journey $git_commits_after_last_tag = []; // Find last git tag // Thanks https://stackoverflow.com/a/12083016/3451846 $git_last_tag = null; exec( 'git describe --tags --abbrev=0', $git_last_tag ); $git_last_tag = $git_last_tag[0] ?? null; // No tag, no party. if( !$git_last_tag ) { echo "Unable to find last git tag\n"; exit( 1 ); } echo "[INFO] Last git tag: $git_last_tag\n"; // Find git commits since last tag $git_log_cmd = sprintf( 'git log --pretty=format:%s %s..HEAD', '%H', escapeshellarg( $git_last_tag ) ); exec( $git_log_cmd, $git_commits_after_last_tag ); // No commits, no party. if( !$git_commits_after_last_tag ) { echo "Unable to list some git commits since last Tag.\n"; echo "Please manually specify some Diff ID like D123 etc.\n"; exit( 1 ); } foreach ($git_commits_after_last_tag as $git_commit_after_last_tag) { echo "[INFO] Found git commit: $git_commit_after_last_tag\n"; } // Find PHID of each commit hash $diffusion_commit_phids = []; $diffusion_commit_search = $client->callMethodSynchronous( 'diffusion.commit.search', [ 'constraints' => [ 'identifiers' => $git_commits_after_last_tag, ], ] ); foreach( $diffusion_commit_search['data'] as $diffusion_commit_data ) { $diffusion_commit_phids[] = $diffusion_commit_data['phid']; } // Find Differential revisions from git commits // Start from commit hash and get Diff PHIDs // https://we.phorge.it/conduit/method/edge.search/ $commit_revisions = $client->callMethodSynchronous( 'edge.search', [ - 'sourcePHIDs' => $git_commits_after_last_tag, + 'sourcePHIDs' => $diffusion_commit_phids, 'types' => [ 'commit.revision', ], ] ); foreach( $commit_revisions['data'] as $commit_revision ) { $diff_phid = $commit_revision['destinationPHID']; $diff_phids[] = $diff_phid; } } // Initialize some stuff $tasks = []; $tasks_phid = []; $tasks_phids_from_diff_phid = []; $USERS_BY_PHID = []; // Start from Diff IDs and get Task PHIDs // https://gitpull.it/conduit/method/edge.search/ $edge_api_parameters = [ // apparently this does not support only PHIDs but also Monograms 'sourcePHIDs' => $diff_phids, 'types' => [ 'revision.task' ], ]; // Get Task PHIDs from Differential Revision PHIDs // https://we.phorge.it/conduit/method/edge.search/ $edge_result = $client->callMethodSynchronous( 'edge.search', $edge_api_parameters ); foreach( $edge_result['data'] as $data ) { $diff_phid = $data['sourcePHID']; $task_phid = $data['destinationPHID']; $tasks_phid[] = $task_phid; $tasks_phids_from_diff_phid[$diff_phid][] = $task_phid; } // Show Diffs that have no Tasks so you can fix on Phorge foreach( $diff_phids as $diff_phid ) { if( empty( $tasks_phids_from_diff_phid[$diff_phid] ) ) { echo "[WARN] Skipped Diff without Tasks: $diff_phid\n"; } } // https://gitpull.it/conduit/method/maniphest.search/ $maniphest_api_parameters = [ 'constraints' => [ 'phids' => $tasks_phid, ], ]; if( $tasks_phid ) { // query Tasks info $maniphest_result = $client->callMethodSynchronous( 'maniphest.search', $maniphest_api_parameters ); foreach( $maniphest_result['data'] as $task ) { // append in known Tasks $tasks[] = $task; // remember User PHIDs since we will need to get their extra info $phid_task_author = $task['fields']['authorPHID']; $phid_task_owner = $task['fields']['ownerPHID']; $USERS_BY_PHID[ $phid_task_author ] = null; $USERS_BY_PHID[ $phid_task_owner ] = null; $phid_task_reporter = $task['fields'][PHABRICATOR_MANIPHEST_CUSTOM_FIELD_REPORTER] ?? null; if( $phid_task_reporter ) { $phid_task_reporter_entry = $phid_task_reporter[0]; $USERS_BY_PHID[ $phid_task_reporter_entry ] = null; } } } if( $USERS_BY_PHID ) { // get users info from their PHID identifiers $users_phid = array_keys( $USERS_BY_PHID ); $users_api_parameters = [ 'constraints' => [ 'phids' => $users_phid, ], ]; $users_result = $client->callMethodSynchronous( 'user.search', $users_api_parameters ); foreach( $users_result['data'] as $user_data ) { $phid_user = $user_data['phid']; $USERS_BY_PHID[ $phid_user ] = $user_data; } } // for each language foreach( $I18N as $lang => $msg ) { $changelog_blocks = []; // NOTE: Phabricator has custom fields that can be populated to retrieve the changelog // in the specified language $phab_maniphest_custom_field_changelog = sprintf( PHABRICATOR_MANIPHEST_CUSTOM_FIELD_CHANGELOG, $lang ); // for each Task foreach( $tasks as $task ) { $task_id = $task['id']; $task_name = $task['fields']['name']; $task_descr = $task['fields']['description']; $phid_task_author = $task['fields']['authorPHID']; $phid_task_owner = $task['fields']['ownerPHID']; $phid_reporter = $task['fields'][PHABRICATOR_MANIPHEST_CUSTOM_FIELD_REPORTER] ?? null; $author = $USERS_BY_PHID[ $phid_task_author ]; $owner = $USERS_BY_PHID[ $phid_task_owner ]; $reporter = null; if($phid_reporter) { $phid_reporter_entry = $phid_reporter[0]; $reporter = $USERS_BY_PHID[ $phid_reporter_entry ]; if($reporter) { $author = $reporter; } } $username_author = $author['fields']['username']; $username_owner = $owner ['fields']['username'] ?? null; $realname_author = $author['fields']['realName'] ?? null; $realname_owner = $owner ['fields']['realName'] ?? null; $task_url = PHABRICATOR_HOME . "T{$task_id}"; $url_author = PHABRICATOR_HOME . 'p/' . $username_author; $url_owner = PHABRICATOR_HOME . 'p/' . $username_owner; // get the most appropriate changelog field or the Task name $changelog_title = $task['fields'][$phab_maniphest_custom_field_changelog] ?? $task_name; // just try to show something useful for a F-Droid changelog $changelog_lines = []; // Task name and URL $changelog_lines[] = $changelog_title; // reporter by (author) // Avoid to repeat the same user twice if( $username_author !== $username_owner ) { $changelog_lines[] = sprintf( $msg['reportedByName'], $username_author ); } // resolved by (owner) $changelog_lines[] = sprintf( $msg['resolvedByName'], $username_owner ); $changelog_lines[] = $task_url; $changelog_block = implode( "\n", $changelog_lines ); $changelog_blocks[] = $changelog_block; } // print all changelog blocks $changelog_content = implode( "\n\n", $changelog_blocks ); // expected changelog file $changelog_path = REPO_PATH . "/metadata/{$lang}/changelogs/{$version_code}.txt"; // save file_put_contents( $changelog_path, $changelog_content ); } diff --git a/metadata/en-US/changelogs/75.txt b/metadata/en-US/changelogs/75.txt new file mode 100644 index 0000000..541d867 --- /dev/null +++ b/metadata/en-US/changelogs/75.txt @@ -0,0 +1,20 @@ +New features: + - Show realtime alerts from GTT into each line (if the API endpoint ever works again) + - Improve the style of the backup screen + +Bug fixes: + - Map: rewrite handling of user location, now the map updates it correctly + - Fix backup not saving favorites + - Fix crash due to locked database + - Fix illegible taskbar (grey text on black background) + - Fix not showing favorites stop while database is being updated + - Add mechanism to close app after back presses + - Fix fragment transitions avoiding recreating shown fragments + +Under the hood improvements: + - Produce LiveData from old databases + - Make new location listener fusing many providers + - Rewrite asynctasks using Kotlin coroutines + - Raise JDK version to 21 + +Version implemented by Fabio Mazza! \o/ diff --git a/metadata/it/changelogs/75.txt b/metadata/it/changelogs/75.txt new file mode 100644 index 0000000..cd503f2 --- /dev/null +++ b/metadata/it/changelogs/75.txt @@ -0,0 +1,20 @@ +Nuove funzionalità: + - Visualizzazione degli avvisi in tempo reale da GTT nella schermata delle linee (se il server GTT ritornerà mai a funzionare) + - Migliorato design della schermata di backup + +Correzioni di bug: + - Mappa: riscrittura della gestione della posizione dell'utente, ora si aggiorna correttamente + - Risoluzione del problema che impediva il salvataggio dei preferiti durante il backup + - Risoluzione del crash dovuto al database bloccato + - Fix: messaggio inferiore illeggibile (testo grigio su sfondo nero) + - Fix: preferiti spariscono durante (e dopo) l'aggiornamento del database + - Aggiunta di un meccanismo per chiudere l'app dopo aver premuto il tasto Indietro + - Fix delle transizioni tra schermate evitando la ricreazione dei frammenti visualizzati + +Miglioramenti interni: + - Generazione di LiveData dai vecchi database + - Creazione di un nuovo listener di posizione che unisce molti provider + - Riscrittura degli asynctask utilizzando le coroutine Kotlin + - Aumento della versione JDK a 21 + +Versione implementata da Fabio Mazza! \o/