diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8a80058..b4dc773 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,8 @@ +v2.7.10 +Add about page to Fluent UI. +Add settings page, allowing changing between UIs. +Add touch scrolling on Linux. + v2.7.9 Add Fluent UI for Windows and Linux. Add split view in landscape when viewing a train. diff --git a/codemagic.yaml b/codemagic.yaml new file mode 100644 index 0000000..cd74c54 --- /dev/null +++ b/codemagic.yaml @@ -0,0 +1,216 @@ +# Automatically generated on 2022-11-17 UTC from https://codemagic.io/app/62eae3fcb833cad7307bdcfa/settings +# Note that this configuration is not an exact match to UI settings. Review and adjust as necessary. + +workflows: + ios: + name: iOS + max_build_duration: 5 + environment: + flutter: stable + xcode: latest + cocoapods: default + cache: + cache_paths: + - $HOME/Library/Caches/CocoaPods + - $FLUTTER_ROOT/.pub-cache + triggering: + events: + - tag + branch_patterns: + - pattern: '*' + include: true + source: true + tag_patterns: + - pattern: v* + include: true + scripts: + - flutter packages pub get + - find . -name "Podfile" -execdir pod install \; + - flutter build ios --release --no-codesign + - | + #! /bin/sh + pwd=$(pwd) + mkdir -p build/ios/Payload/infotren.app + cp -r build/ios/iphoneos/Runner.app/* build/ios/Payload/infotren.app + mkdir -p build/ios/ipa + cd build/ios + zip -r Payload.zip Payload + cd "$pwd" + cp build/ios/Payload.zip build/ios/ipa/infotren.ipa + artifacts: + - build/ios/*.zip + - build/ios/ipa/*.ipa + - /tmp/xcodebuild_logs/*.log + - flutter_drive.log + publishing: + email: + recipients: + - dan+codemagic@dcdev.ro + scripts: + - | + #! /bin/sh + curl -H "X-Tag: $CM_TAG" -H "X-Codemagic-Build-UUID: $CM_BUILD_ID" -H "X-Codemagic-Build-Status: $CM_BUILD_STEP_STATUS" https://webhook.dcdev.ro/hooks/infotren-codemagic-done + android: + name: Android + max_build_duration: 7 + environment: + vars: + FCI_KEYSTORE_PATH: /tmp/keystore.keystore + FCI_KEYSTORE: Encrypted(Z0FBQUFBQmpkaHBXalZGdkpXUGcwckZkbmRnOXRZN3Bhbld4MVdBSFd2RW1JaDluVU9FOGRZS21vZmMtMkttRHNRa3IwOWRtOEQycERUN3N2SU8wU1RadmRaSjBiRlN1UEhla2lMMXJkM1BlaGRxWjFZcUFHRmlyNXROU0dPbjk0ZnN1cWRrTFN5emdtNnd0S3Jjc19oQk5TWGx6TXNwOTBmTWtHZVRoaE9uV3A3V3VNRlV1NHA1a0VXcHpwX1dzdmRYamNoeXJtczU0N2pmNXBfcnptRWdudDliT0pfVEExYU9EaW55UlRCN1NJZDRUOEQ2RHZrRlVWdEVSVEtoQ0NFVkNDZ3R4bFFDMk1FNDRUeG1MbjRoeFRTQWtkSnlKbjhxeHZKejdsMGtTLVN0WjFaT2dkM1RJM05oUldsQklDNHNBRW92dF9NMEZjN1JDWWRSdjZLaG9LaElIUGdiRGVzMWMxNGVua0loNFZCeFJvekRIUjRPY3dHcHlFa1pwTm1UdWtFVjQ3OGFMSlZuVDB1cUYyTUhtb0tlejVsc21aWE1kLTVxR0JXVVBLRXB2b1pYM1FPOFNOTGJ4bUNIbGt0dXZocnZFYjBqa1BQR3kyRkN1VDg2MF9YMzAzRm5yTGc5d1F4U3pHVlE1b1ZOaG9ZcEdCVS1mMVhieWZhY1FkODEtWlA3c2w3Q2g5OHN3VnlENnR5eWhyUTlwUEVHNzZYdHZlSG8xMHZBRXlBbnQxU29WTkRTZlM3VGN2eWszRFRhMzVoTHMwR0x3ajhLMWpsbGxpaWNNWlJzbFByUnhLbFZKMEU5b0J6RVNpX1VVVzhlTnpqMkNQb2xEaXhVejJqWXFQQ0tyT09zdk1Vc09VXzF4aWpJRlNzSlpwSTlTWFRxZzl0dmNBTmxOZ2YzYXQzMGduNGluMkloQ3RxNWE5d2VWaGhzZmZtWVB0Vk5hNHdSdDNCWlBROVhtX2dLdHpDRFFwdENwNHlxaFMzVnM2M2FuWXFodjJKeU9KVUlmbURVUGRVM0JsSzdaSGcwbDFUY1lPOFpfdlg0aEFjdVc3TVMtcmlrS3ZrMFNUX2U2ZTZLczZsS0d6SEdKUDlzWDgxRXlEanYzejduMDZiRk0zZU9kWm5lOVdWbXoxUzBlNzZrR3dxSEV2V3lOSzlFbDk0ZXcyc2k5cHRXS0dzVENoM3ZvVVVHWkowRjRWUmJPTm1ESXJucUtzSE55RFlvQ2RTZXYwdDM3dVFTLW4ydTFUWVdxVWZZZWZWdmtRa2dZQVBhRzlUUHdaLUdtV0xnWE5ZQmNqa2xjUVZYVmtrNWJYcThJZFk2bXh6RmpDS0xVMDBqY3QwVUJBVEpmZFRuT2J6SldGcDM0STV5QjVIZjE2bDA3Ymg3N3pHci1aYkJRN2owUkN3cWZnMjJUQTdiVjRGaGJGdHZ0QzJIbm1OVGRJS044MzBRN3liZ1lhUHBYbUlINDQ3Zm5ZaG03aUpvYkpkUzhfbTVtUWtPUzhLQi1RNHp3aVdHNXY3SncwM3lxV2dHckN6Y2xaRzNOTUxzNDhJeXpKVG94Umd0NC0wa3NxSUdPczlGWTdfWFFPVTlYanh5VWp2TXhZYkQyRTlNRW1KRVhXcDQtRmpCbTBlSUxtRnhzMFU5M0QwMzhrdEpDZzhyTnlrN0UwUG5VS3lxbDd3RmFhMEhFcElZRzgyc0FfelFqVW5UNFFKbkNJVXpYd0IweHJFU2tieTZuMFpXX3hvN3pqSGlLMmJwWllWcllhSFFGVk9YUE43aFJkNWxldUJvVEV1VEsxV3pYeHZTVVVXUkc2MnQ0VWItV190SktnQVBxT3pVMkNZcVpVTGM2ZmVPVk5XVWx3aVliVDUzb0dJbzlxVWowa0lQUEdQc3lIaGs2eHRWUWdyZmwwMnJxeW1maG4yWEpTb3hQYTRGWW1fSWJXOXZKS2hTaG9SU1otQndraXQ2S1FRVDllSTZXOGFENVBSc2FsMHFpNHE3RGVmU3dvWDRuWUtoNF9HcFc3SGNycGNqME1fVHh1dHNGaGh6WmJ4eGRxOFhaTHRKbHRhQUlDU1FCRjlBQlgwY1lhQUVTc0YtTzBOYmptTjc4S1M5dnk5OUFvQ3hHMGdIWExneWFQYXNFX01VWTRsbzQ1dFBVLXlRZmxMMGtiOUxVbHYyXzB1NFlNRlEyVUZxUlhyMVNUUzlNMGNYYkxkM3hsZWdyVkx0Tm4xREk5RXg0SW9ycl82NnlXd0ZSLWNBZkM1ZE5QeXowNVlYX0ZxZkUxTi1pUE1xOVp6dWU2cTNUbTFnV3p5Ym5Nbi1OMTgtVDBQcGVTMVA3V25WWGNoMHZvME5UZ0NiaWRKUEFoLUFzemJ4Y1VHVzFybkNMR0oxRlgzRzNNcnhfUUl0bXcwcDlJSWtJY2xudWI5SFFWdHpGa2RHbF8xYm92Y0taVEQzenhsMEhiRl9Lb0Nhamg0ZHl5ZzQ3cnlobDlJQXlKdm1sNjJVTmp2elo0eWZfTll4dlJqdmhCV2lUeW5aVlFNT1dTZUI2Rzh4TGxmTElMd0lqbG1LdzhuUm51cEw3bFh5cmpyU2hyd2ZIR1hhTkk4MFhGWVdkOV9UOW52UHJ6SzhfamhXNnJtb3pPTkVnM1dBZnNhTUM1cE9CNERHdlJKOHQ3b1gwOW1MXzk2Rk9PUVpjWEFjSEZTU1FDZWJKNDZUOHFwMzRCc21icWs2TkJTbUpzck16ZXFncFF3bmtIY052V1JyN0tkN1NyWXJOR2RYblZPQ2htQUJvWHU0Yktrd1licERiWk5BQllUTGVNd1QtWDdTZ3JJS0p1NFdVQkZoRS1YR0hFc3lKdkxqNDY2WEJQdnl6WWpPZkp5MGdtMVBNZHB5LUZGdUk5WnZiYU4xNlhBeGRnSnFRdzk1eW1Cb2lqcGc3cVFNWkJBQmdWYzNRdVNhMUdOOFNneTJZdmdUSEcxc3F6QlZEeFlkT1VjWExENnZ2dnFOcnA1SWNudWVmOTIxNzRsTXVBN1dHUG9oYVZYV2dsaGdZX2FuWVprd3d6Z1JGQXk3Xy01Vy1QdTVibWp2elFuejczTmVSS2VWaFh0blItNTB5NndGa216YlV5T2Z2V19oVWZTZnpNanhDUUk3TUZ2dUxxbGtDdU4xRnVSWkxocWhsR3gzZFhwVzRPbUVyamlQN3BYeXVrTWVEMGlSWTk5OW1BbURQX1duTG50TWU3UXJmd0xuVzZmTG8tRmlzbGlBcjcxc2xiWTlWc3hXa281eFBPdHRJdFNNS0lJaXM5X1FndnJwbkVxUEFxdnMwTjFXTnhUUlhKQ1o0ZjBEUHVQelFoNlRTbWcwN01hYmFuQ3V3RXl2ZEUtOFdPYWRhZWZudHl6aW5idVE5RzN2QVlSQVBWb014NFpNXzdzbXpWTWJBT1lkSnNTcjBibUJVRDJOV0F2SlRXWl9abUNEN2NLTHRCdHVXd3RiZEVqOGtZZ0hwRGV1Y05qMk1PeHRtUk5NSXZoMUtiMnBCSXpkT2Y2UUxyc1ZsRjM2UTB5WUY2eGhlUXFva2NuUE81d2JGaE9pU2hTYWdkSWhyYjJoYlVjT1g0Y2ZvMnQ5aGtITXNEZkxzUy1tRHczc1E5QzVpeXVSdFJ6UWcxR0dfeVp4dEZtbzVBNVlGQkJCRWJ6WUlXYTB5ZGlRM3A4UWV4TVpmR2NVQUF2d2lEUnYtX2pCMF9OdzFjOUY2U29DZUQ3RUw3QXZ6ZHQtcTBwZVM5OWY3cFJBczNoOGhQR3gzQWkxU09lMGk1Z1g5dllUWVpMVThhOE1wQ2l0Ul9wZ1JLaTdDYXBjS0hYZmdOdmZ1T1dMZDAwbFpFbGVoa2plNm5ySXRWLXFQZVlyaVp3WE5Qc0k3SlN1Zk5rRTlBOUNNZmtxb0h1MEhYTXZ1U0o2UzlkeU5wX3BSWmtnSnE1YmQ0ZHFaNjZYWXhRbU5Ic1FLWUk3cHNBYVNQVG9kalg2ZzJDNUFod29fcHhueXA2SjJFQU9RdXZydENudGZ4Z0IxWGFHMXIzZlpBc3BvcC1pQXdsQVpkOEZOWmJ0dHJpTVlOX2wzemdFUC1PYWdZeTgyUWxxaDBDeFZiRE1fTDZZWng2Y0dKX1phV0dGNl9xanVDU1NKS0JiY1IxSmx0RExzVVVROU90U0t2ZmprNDVqQkpRT2xoWWNNVHdXcHR6MGJfd2wzNXpDNFRIRXlpcGtvc0ZFOGZnaTlYMjZ5UWJfQmZ0Tzdwb0J4RVJLS2dHanMtXzM2STIwb2Y4M0JZZGhMMVBVWUpTaUNvaXpyUkVyZmdPRS1YS3lfR2N1TF8xZTU1T0NPeno4RjFBRlJVNXN6aWVLWGh0YmNYWmVpbUtPRVdIb1BmN0syNFpibEwxanFsN0N5Y2RBT2txTWh2UjU3SnZnMjZJbVBjZk5MTmFqQUp0UzJ6NkJESDJmaDJLZHU1bzBXSC0zRklwakwyWllVekVCRTgyeXA1T0VNXzVrcXJWbDAyVXFsVFBXNXpQN0RESE1Ra00xMmZzb1VrVHhzamw2RG9mRHFWd1RxN1c0QUJXSXBkN1Z5M2NnSUh4b29fYnhjMjkwX1Jzc2dCZU40R0xTRnQ1b3o1ZWlEVjNNMVl2U3B6NWdDWG02dHRFVGRwaFRSXzFPMlVOcDk4dXNxYXFHZEx6TDN2WFJENHZVSlhKREFsM3pZZkMzYzhNNlNuUVhuTVI5VThTdGkzZnlsbEVpMUo0aVoyMVhvVkVvOXlJblZGeFlLR0I1Y09kSEFzNHUxVlI2OG9CMDhqaEhEVEI3T3ZxYV8tU2VMajd1Q1VNSVJDVk5xUXdheW9ESVJzRjBONGw3Z0U0Z1VBSGNzN0RYRTQ1Q0FMV21BUE10TE1FWWYxNnl1TjYyZ0dQMGxuNHZqcnNuenpSd0hHNHdZQkRRQTlHUjM2ZnJhS2dSOWl6bkpoSzlGa24xdE0wLTk1bXpVU1d3dnBpQ3JvTmFUSWJWckNlV1VCNlYyUVZLamx5aW8xWDc3b1JOYjdnWjBpZjdlbEdpaHltU09pSGNBMExJY09fQ2dPT21MWThvWE1LZjNsM0gwbk9zWmZKZnRtYkRXdjZ2VjJ0YzNzaS1oWUpzbUhYemt6OGpJVVh4aWg5cmx6QnlfWGJsakxEQXZSc2JzYVBSbzBLWVVPRkcxLWtuUlJOUUdEYWY3blRIR1BXNXJ5VExGeXhLWGFZMWZyLVpmNmdvN0pFRjFJWnNyUjBoSFhvSDdHZWgyOGduQS0yR2M0RFBZTTJ6T3NDQmtQRUpISHA4SHJxMHR3ZllYU0FhVlVsVGJFWm0zazFnbGo0SEhhY210S3Y5WXUycnB3UGtJdUU1MUtlbVRGbHZoRklhTnNVdDZNT3BSZ21Ia0xOMC1UM2F0RllrRF9WOV9nMU40bWdyVDBYX01wQThrdkp4LU1Cdm5ZMEJQaWxQZVdsN0hKN290S1FvMGM1U3BnaWhTM0Q1c2hZTXdibHZQVXhwRWx4dk9mbW13bEFkdEpya0N5YkdDWklDdTAyaldjSXRoblJ6Z3JMLVBWMDVaOXJCN3pFYmRQbGh3ek8tNG1WTHdqYW9UbWl0djZObWNsQ29zcjI2WllyLVpFOGZ0NktkNTJiTFB3dW45RXlEOXhLVElJNmhkWXdXc3k2N2I2dkc5TExhSXlobUdfclR5VEJyR3RqeUFrNlI5b1MtdENZZklONXU5aVhWTmFGTUdfS0xNX3V1WlRhWm5BNGUtSV9uUnU2eWVlNmtoSFZxdzZHbmZ6bUowZG5lTFd3cGV4ZUwyWWZRTjFweUsxQmIyTFJnNnlVQmlHT0REZnNZWXVEeWVHR0x4NVdaTWRXTVZ5ZDFXMjh3TmtMRlJHUndjdDBpNDdBZTIzWS1lZWpFcDVxWDN1dHZ2VWNDRmhIU2pwanlYcmFOQUFpSElYYXJMQzVVaDZjZ29taFVHamlnRWstbDlGN2p4RlE3NVc5TTVsaW1rTnpLMlViNHdjc0pMX3dxd002dkJxM18wRkluREZ4aEtPbGdQLUFZSktWMENrZWRqeHFUNmFCZ3labml2aG5GLWFOQ2ptbWkyMlBEWHN0bmZuRDRodENlcEJUQUZ2TzBkU09JYjJiSnFiNmNQd3p6XzJ4eHYtWEFEY2dzeWdWTEl4NTNURUpNQmo5dXFvbVN5a2d2dk5ySXE2cURqMUtjU3VQd05kdmF3czVwSWhmRkg3SDlPVmZFTkRLZkI5WXlydHhyUlhvemYta1lsQ3c5bG1jd3JDV2h1X1lQeE1MNTlxREQ3R2FhdEJoSVdSZkRUbzB3Wk10NGVkSTVmV29ZeVVVMW1yaW1yRENsdU82SzFORUt6OXloNHBYZFZrQjB6VlF4VVljZHFreVlsb05RYi1MLWx4aXFBdVlGS09LMTFLcU5wRVdYam9XVm1GakhkZGY1TkhVRWV0MHZFeklrUGxTbEM4TVFPN0hRZ3hqUVp5QlMxTUh2ZGNNLXV5X0R6Y1NWRlQydGZPMDNPbk5rUmE2Y3pPeHI3Q19kUC1wVV9uZms9) + FCI_KEYSTORE_PASSWORD: Encrypted(Z0FBQUFBQmpkaHBXTmVMX3VqMHJPMjFYLTRhcmdLSVNXMjhvN2U4aFFramdmT3BzNUYzbGl6ZzdPTUtYblVBN2RialVacF9KXzl1Y0ZXYk9XQ2NnbEhZRnZ0U1JSck9ubFhqb1gyOGx4RTNMQVVydGRhb3JLSUk9) + FCI_KEY_PASSWORD: Encrypted(Z0FBQUFBQmpkaHBXcHg3UWN6ckM2MWpCYzd6NjdkUXFNWGQ1SERlVGl5ZVg0TDg1aU9pLVZkWGtkWDhWM25faDBuOHhBTGNhYjlMMGhMd2J0d0oyYV9yalZhcjIyYjdiZUZaUzZQdG80Zk1CaHotZUdtSkJlYWc9) + FCI_KEY_ALIAS: Encrypted(Z0FBQUFBQmpkaHBXZ2xGZTBudmRLWFEwTnAtdkdHR25RVkJkeTE5MFA3U1lraU0wOU5LTzBfb1RENkdoeHA3ZGx5SmZBdWxyekFVRkI1SnR3bi16blpiWEk2eEZDTF9QOUE9PQ==) + flutter: stable + xcode: latest + cocoapods: default + cache: + cache_paths: + - $HOME/.gradle/caches + - $FLUTTER_ROOT/.pub-cache + triggering: + events: + - tag + branch_patterns: + - pattern: '*' + include: true + source: true + tag_patterns: + - pattern: v* + include: true + scripts: + - | + # set up key.properties + echo $FCI_KEYSTORE | base64 --decode > $FCI_KEYSTORE_PATH + cat >> "$FCI_BUILD_DIR/android/key.properties" < "$FCI_BUILD_DIR/android/local.properties" + - flutter packages pub get + - flutter build appbundle --release --dart-define DOWNLOAD=apk + - | + # generate signed universal apk with user specified keys + android-app-bundle build-universal-apk \ + --bundle build/**/outputs/**/*.aab \ + --ks /tmp/keystore.keystore \ + --ks-pass $FCI_KEYSTORE_PASSWORD \ + --ks-key-alias $FCI_KEY_ALIAS \ + --key-pass $FCI_KEY_PASSWORD + artifacts: + - build/**/outputs/apk/**/*.apk + - build/**/outputs/bundle/**/*.apk + - build/**/outputs/bundle/**/*.aab + - build/**/outputs/**/mapping.txt + - flutter_drive.log + publishing: + email: + recipients: + - dan+codemagic@dcdev.ro + scripts: + - | + #! /bin/sh + curl -H "X-Tag: $CM_TAG" -H "X-Codemagic-Build-UUID: $CM_BUILD_ID" -H "X-Codemagic-Build-Status: $CM_BUILD_STEP_STATUS" https://webhook.dcdev.ro/hooks/infotren-codemagic-done + linux: + name: Linux + instance_type: linux + max_build_duration: 5 + environment: + flutter: stable + xcode: latest + cocoapods: default + cache: + cache_paths: + - $HOME/.gradle/caches + - $HOME/Library/Caches/CocoaPods + - $FLUTTER_ROOT/.pub-cache + triggering: + events: + - tag + branch_patterns: + - pattern: '*' + include: true + source: true + tag_patterns: + - pattern: v* + include: true + scripts: + - flutter packages pub get + - flutter build linux --release --dart-define DOWNLOAD=linux + - | + #! /bin/sh + pwd=$(pwd) + for arch in x64 arm64; do + if [ -d build/linux/$arch ]; then + echo Packaging arch $arch + cp linux/install.sh linux/infotren.desktop build/linux/$arch/release/bundle + cd build/linux/$arch/release + cp -r bundle infotren + zip -r infotren-linux-$arch.zip infotren + cd "$pwd" + fi + done + artifacts: + - build/linux/*/release/*.zip + - '*.snap' + - flutter_drive.log + publishing: + email: + recipients: + - dan+codemagic@dcdev.ro + scripts: + - | + #! /bin/sh + curl -H "X-Tag: $CM_TAG" -H "X-Codemagic-Build-UUID: $CM_BUILD_ID" -H "X-Codemagic-Build-Status: $CM_BUILD_STEP_STATUS" https://webhook.dcdev.ro/hooks/infotren-codemagic-done + windows: + name: Windows + instance_type: windows_x2 + max_build_duration: 5 + environment: + flutter: stable + xcode: latest + cocoapods: default + cache: + cache_paths: + - $HOME/.gradle/caches + - $HOME/Library/Caches/CocoaPods + - $FLUTTER_ROOT/.pub-cache + triggering: + events: + - tag + branch_patterns: + - pattern: '*' + include: true + source: true + tag_patterns: + - pattern: v* + include: true + scripts: + - flutter packages pub get + - | + # build windows + + flutter config --enable-windows-desktop + flutter build windows --release --dart-define DOWNLOAD=windows + cd build\windows\runner\release + 7z a -r ..\infotren-win.zip .\* + # Disable MSIX for now + # - | + # # Remove this script if the msix pub has already been added to your repository + # flutter pub add --dev msix + # - flutter pub run msix:create + artifacts: + - build/windows/runner/*.zip + - build/windows/**/*.msix + - flutter_drive.log + publishing: + email: + recipients: + - dan+codemagic@dcdev.ro + scripts: + - | + #! /bin/sh + curl -H "X-Tag: $CM_TAG" -H "X-Codemagic-Build-UUID: $CM_BUILD_ID" -H "X-Codemagic-Build-Status: $CM_BUILD_STEP_STATUS" https://webhook.dcdev.ro/hooks/infotren-codemagic-done diff --git a/lib/pages/about/about_page.dart b/lib/pages/about/about_page.dart index c5835bd..31c2765 100644 --- a/lib/pages/about/about_page.dart +++ b/lib/pages/about/about_page.dart @@ -3,6 +3,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:info_tren/api/releases.dart'; import 'package:info_tren/models.dart'; import 'package:info_tren/pages/about/about_page_cupertino.dart'; +import 'package:info_tren/pages/about/about_page_fluent.dart'; import 'package:info_tren/pages/about/about_page_material.dart'; import 'package:info_tren/providers.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -21,6 +22,8 @@ class AboutPage extends ConsumerWidget { return const AboutPageMaterial(); case UiDesign.CUPERTINO: return const AboutPageCupertino(); + case UiDesign.FLUENT: + return const AboutPageFluent(); default: throw UnmatchedUiDesignException(uiDesign); } @@ -31,7 +34,7 @@ abstract class AboutPageShared extends StatefulWidget { const AboutPageShared({super.key}); } -abstract class AboutPageState extends State { +abstract class AboutPageState extends State { static const String download = String.fromEnvironment('DOWNLOAD'); final String pageTitle = 'Despre aplicație'; diff --git a/lib/pages/about/about_page_cupertino.dart b/lib/pages/about/about_page_cupertino.dart index 6c25f6b..32d466f 100644 --- a/lib/pages/about/about_page_cupertino.dart +++ b/lib/pages/about/about_page_cupertino.dart @@ -3,14 +3,14 @@ import 'package:info_tren/components/cupertino_divider.dart'; import 'package:info_tren/pages/about/about_page.dart'; import 'package:url_launcher/url_launcher.dart'; -class AboutPageCupertino extends StatefulWidget { +class AboutPageCupertino extends AboutPageShared { const AboutPageCupertino({super.key}); @override State createState() => AboutPageStateCupertino(); } -class AboutPageStateCupertino extends AboutPageState { +class AboutPageStateCupertino extends AboutPageState { @override Widget build(BuildContext context) { return CupertinoPageScaffold( diff --git a/lib/pages/about/about_page_fluent.dart b/lib/pages/about/about_page_fluent.dart new file mode 100644 index 0000000..9977c62 --- /dev/null +++ b/lib/pages/about/about_page_fluent.dart @@ -0,0 +1,140 @@ +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter/services.dart'; +import 'package:info_tren/pages/about/about_page.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AboutPageFluent extends AboutPageShared { + const AboutPageFluent({super.key}); + + @override + State createState() => AboutPageStateFluent(); +} + +class AboutPageStateFluent extends AboutPageState { + @override + Widget build(BuildContext context) { + return NavigationView( + appBar: NavigationAppBar( + title: Text(pageTitle), + ), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: Text( + 'Info Tren', + style: FluentTheme.of(context).typography.display, + ), + ), + if (packageInfo != null) + Center( + child: Text( + packageInfo!.packageName, + style: FluentTheme.of(context).typography.caption, + ), + ), + // ListTile( + // title: Text(versionTitleText), + // subtitle: localChangelog.isEmpty ? null : Text(localChangelog.first.title), + // ), + const Divider(), + for (final log in mergedChangelogs) ...[ + Padding( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( + log.version.toString(), + style: FluentTheme.of(context).typography.title, + ), + ), + if (localChangelog.isNotEmpty && log.version == localChangelog.first.version) + Container( + decoration: BoxDecoration( + border: Border.all( + color: FluentTheme.of(context).inactiveColor, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + currentVersionText, + style: const TextStyle( + inherit: true, + ), + ), + ), + ), + if (remoteChangelog.isNotEmpty && log.version == remoteChangelog.first.version && (localChangelog.isEmpty || localChangelog.first.version != log.version)) + Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + latestVersionText, + style: TextStyle( + inherit: true, + color: Colors.green, + ), + ), + ), + ), + if (AboutPageState.download == 'apk' && log.apkLink != null) + GestureDetector( + onSecondaryTap: () { + Clipboard.setData(ClipboardData(text: log.apkLink!.toString())); + // ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + // content: Text('Link copied to clipboard'), + // )); + }, + onLongPress: () { + Clipboard.setData(ClipboardData(text: log.apkLink!.toString())); + // ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + // content: Text('Link copied to clipboard'), + // )); + }, + onTap: () { + launchUrl( + log.apkLink!, + mode: LaunchMode.externalApplication, + ); + }, + behavior: HitTestBehavior.translucent, + child: const Tooltip( + message: 'Download APK', + child: Padding( + padding: EdgeInsets.all(4), + child: Icon(FluentIcons.download), + ), + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: log.description, + ), + ), + ), + ], + ], + ), + ), + ); + } +} diff --git a/lib/pages/about/about_page_material.dart b/lib/pages/about/about_page_material.dart index 94d3847..b069ffc 100644 --- a/lib/pages/about/about_page_material.dart +++ b/lib/pages/about/about_page_material.dart @@ -3,14 +3,14 @@ import 'package:flutter/services.dart'; import 'package:info_tren/pages/about/about_page.dart'; import 'package:url_launcher/url_launcher.dart'; -class AboutPageMaterial extends StatefulWidget { +class AboutPageMaterial extends AboutPageShared { const AboutPageMaterial({super.key}); @override State createState() => AboutPageStateMaterial(); } -class AboutPageStateMaterial extends AboutPageState { +class AboutPageStateMaterial extends AboutPageState { @override Widget build(BuildContext context) { return Scaffold( @@ -138,4 +138,4 @@ class AboutPageStateMaterial extends AboutPageState { ), ); } -} \ No newline at end of file +} diff --git a/linux/infotren.desktop b/linux/infotren.desktop new file mode 100644 index 0000000..3e1ac24 --- /dev/null +++ b/linux/infotren.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Encoding=UTF-8 +Name=Info Tren +Comment= +Exec= +Icon= +Terminal=False diff --git a/linux/install.sh b/linux/install.sh new file mode 100755 index 0000000..3be36ea --- /dev/null +++ b/linux/install.sh @@ -0,0 +1,39 @@ +#! /bin/sh +install_dir="$1" +if [ -z "$install_dir" ]; then + echo "Please specify a directory to install InfoTren to." + echo "Example:" + echo " $0 ~/infotren" + exit 3 +fi + +if [ ! -d "$install_dir" ]; then + if [ -d $(dirname "$install_dir") ]; then + mkdir "$install_dir" + else + echo "$install_dir doesn't exist. Please specify a directory to install InfoTren to." + echo "Example:" + echo " $0 ~/infotren" + exit 1 + fi +fi + +if [ ! -f ./infotren.desktop ]; then + if [ -f "$(dirname $0)/infotren.desktop" ]; then + cd "$(dirname $0)" + else + echo "Run this script from inside the infotren directory." + exit 2 + fi +fi + +echo "Installing InfoTren to $install_dir" +cp -r . "$install_dir" +if [ -z "$XDG_DATA_HOME" ]; then + XDG_DATA_HOME=~/.local/share +fi +if [ ! -d "$XDG_DATA_HOME/applications" ]; then + mkdir -p "$XDG_DATA_HOME/applications" +fi +echo "Installing infotren.desktop to $XDG_DATA_HOME/applications/infotren.desktop" +cat infotren.desktop | sed "s|Exec=|Exec=$install_dir/info_tren|g" > "$XDG_DATA_HOME/applications/infotren.desktop" diff --git a/pubspec.yaml b/pubspec.yaml index 1c99d8d..2ca02e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: O aplicație de vizualizare a datelor puse la dispoziție de Inform # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 2.7.9 +version: 2.7.10 environment: sdk: ">=2.17.0 <3.0.0"