diff --git a/gradle.properties b/gradle.properties index c82141d..424926a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,6 +22,9 @@ android.enableJetifier=false # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true + GROUP=com.mxalbert.zoomable POM_ARTIFACT_ID=zoomable VERSION_NAME=1.7.0-SNAPSHOT diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a67ba52..93ab731 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,24 +1,23 @@ [versions] -agp = "8.5.2" +agp = "8.9.0" sdk-min = "21" -sdk-target = "34" -sdk-compile = "34" -buildTools = "35.0.0" -binaryCompatibilityValidator = "0.16.3" -maven-publish = "0.29.0" -kotlin = "2.0.21" -dokka = "1.9.20" -coroutines = "1.8.1" -compose-jetbrains = "1.6.11" -compose-jetpack = "1.6.8" -compose-compiler = "1.5.15" -ktor = "3.0.0" -androidx-activity = "1.9.1" -coil = "2.7.0" +sdk-target = "35" +sdk-compile = "35" +buildTools = "35.0.1" +binaryCompatibilityValidator = "0.17.0" +maven-publish = "0.31.0" +kotlin = "2.1.10" +dokka = "2.0.0" +coroutines = "1.10.1" +compose-jetbrains = "1.7.3" +compose-jetpack = "1.7.8" +ktor = "3.0.3" +androidx-activity = "1.10.1" +coil = "3.1.0" jUnit = "4.13.2" truth = "1.4.4" test-ext-junit = "1.2.1" -robolectric = "4.13" +robolectric = "4.14.1" [libraries] kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } @@ -26,7 +25,6 @@ agp = { module = "com.android.tools.build:gradle", version.ref = "agp" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } -compose-compiler-jetpack = { module = "androidx.compose.compiler:compiler", version.ref = "compose-compiler" } compose-runtime-jetbrains = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-jetbrains" } compose-runtime-jetpack = { module = "androidx.compose.runtime:runtime", version.ref = "compose-jetpack" } compose-foundation-jetbrains = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose-jetbrains" } @@ -35,12 +33,13 @@ compose-ui-util-jetbrains = { module = "org.jetbrains.compose.ui:ui-util", versi compose-ui-util-jetpack = { module = "androidx.compose.ui:ui-util", version.ref = "compose-jetpack" } compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "compose-jetpack" } compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "compose-jetpack" } -ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-java = { module = "io.ktor:ktor-client-java", version.ref = "ktor" } ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" } ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } -coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } +coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } +coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" } +coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" } jUnit = { module = "junit:junit", version.ref = "jUnit" } truth = { module = "com.google.truth:truth", version.ref = "truth" } test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "test-ext-junit" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c35211..9bbc975 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0..37f853b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..faf9300 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index e54cc27..3c713c0 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -104,23 +104,7 @@ dependencies: "@types/node" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" - integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" - integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.5": +"@types/estree@^1.0.5": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== @@ -177,7 +161,7 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -400,13 +384,6 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abort-controller@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -928,10 +905,10 @@ engine.io@~6.6.0: engine.io-parser "~5.2.1" ws "~8.17.1" -enhanced-resolve@^5.17.0: - version "5.17.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" - integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== +enhanced-resolve@^5.17.1: + version "5.18.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" + integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -1010,11 +987,6 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -1613,10 +1585,10 @@ karma-webpack@5.0.1: minimatch "^9.0.3" webpack-merge "^4.1.5" -karma@6.4.3: - version "6.4.3" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.3.tgz#763e500f99597218bbb536de1a14acc4ceea7ce8" - integrity sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q== +karma@6.4.4: + version "6.4.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.4.tgz#dfa5a426cf5a8b53b43cd54ef0d0d09742351492" + integrity sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w== dependencies: "@colors/colors" "1.5.0" body-parser "^1.19.0" @@ -1648,6 +1620,13 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +kotlin-web-helpers@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kotlin-web-helpers/-/kotlin-web-helpers-2.0.0.tgz#b112096b273c1e733e0b86560998235c09a19286" + integrity sha512-xkVGl60Ygn/zuLkDPx+oHj7jeLR7hCvoNF99nhwXMn8a3ApB4lLiC9pk4ol4NHPjyoCbvQctBqvzUcp8pkqyWw== + dependencies: + format-util "^1.0.5" + launch-editor@^2.6.0: version "2.9.1" resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.9.1.tgz#253f173bd441e342d4344b4dae58291abb425047" @@ -1804,10 +1783,10 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@10.7.0: - version "10.7.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.0.tgz#9e5cbed8fa9b37537a25bd1f7fb4f6fc45458b9a" - integrity sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA== +mocha@10.7.3: + version "10.7.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" + integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== dependencies: ansi-colors "^4.1.3" browser-stdout "^1.3.1" @@ -1858,13 +1837,6 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - node-forge@^1: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" @@ -2548,11 +2520,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -2641,11 +2608,6 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - webpack-cli@5.1.4: version "5.1.4" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" @@ -2733,12 +2695,11 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.93.0: - version "5.93.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.93.0.tgz#2e89ec7035579bdfba9760d26c63ac5c3462a5e5" - integrity sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA== +webpack@5.94.0: + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== dependencies: - "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.5" "@webassemblyjs/ast" "^1.12.1" "@webassemblyjs/wasm-edit" "^1.12.1" @@ -2747,7 +2708,7 @@ webpack@5.93.0: acorn-import-attributes "^1.9.5" browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" @@ -2777,14 +2738,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -2823,12 +2776,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== - -ws@^8.13.0: +ws@8.18.0, ws@^8.13.0: version "8.18.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== diff --git a/sample/androidApp/build.gradle.kts b/sample/androidApp/build.gradle.kts index 46f4743..2be426e 100644 --- a/sample/androidApp/build.gradle.kts +++ b/sample/androidApp/build.gradle.kts @@ -18,7 +18,7 @@ android { applicationId = "com.mxalbert.zoomable.sample" minSdk = libs.versions.sdk.min.get().toInt() targetSdk = libs.versions.sdk.target.get().toInt() - resourceConfigurations += "en" + androidResources.localeFilters += "en" val libVersion = property("VERSION_NAME") as String val appVersion = libVersion.substringBefore('-') versionName = appVersion diff --git a/sample/shared/build.gradle.kts b/sample/shared/build.gradle.kts index b0096e7..9a2d4b7 100644 --- a/sample/shared/build.gradle.kts +++ b/sample/shared/build.gradle.kts @@ -39,36 +39,30 @@ kotlin { implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) - } - - val nonAndroidMain by creating { - dependsOn(commonMain.get()) - dependencies { - implementation(libs.ktor.client.core) - } + implementation(libs.coil.compose) } val desktopMain by getting { - dependsOn(nonAndroidMain) dependencies { + implementation(libs.coil.network.ktor3) implementation(libs.ktor.client.java) } } androidMain.dependencies { - implementation(libs.coil.compose) + implementation(libs.coil.network.okhttp) } iosMain { - dependsOn(nonAndroidMain) dependencies { + implementation(libs.coil.network.ktor3) implementation(libs.ktor.client.darwin) } } val wasmJsMain by getting { - dependsOn(nonAndroidMain) dependencies { + implementation(libs.coil.network.ktor3) implementation(libs.ktor.client.js) } } diff --git a/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.android.kt b/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.android.kt deleted file mode 100644 index da4e3fe..0000000 --- a/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.android.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.mxalbert.zoomable.sample - -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.safeDrawing -import androidx.compose.runtime.Composable -import androidx.compose.runtime.NonRestartableComposable - -internal actual val WindowInsets.Companion.safeDrawing: WindowInsets - @Composable - @NonRestartableComposable - get() = WindowInsets.safeDrawing diff --git a/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.android.kt b/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.android.kt index 7b092f5..7b62881 100644 --- a/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.android.kt +++ b/sample/shared/src/androidMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.android.kt @@ -1,46 +1,8 @@ package com.mxalbert.zoomable.sample -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.pager.HorizontalPager -import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.material.SnackbarHostState import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import coil.compose.AsyncImagePainter -import coil.compose.rememberAsyncImagePainter -import coil.request.ImageRequest -import coil.size.Size -@OptIn(ExperimentalFoundationApi::class) @Composable fun ZoomableApp() { - val snackbarHostState = remember { SnackbarHostState() } - - ZoomableApp(snackbarHostState = snackbarHostState) { - HorizontalPager(state = rememberPagerState { Images.size }) { index -> - ZoomableImagePage(snackbarHostState = snackbarHostState) { - val painter = rememberAsyncImagePainter( - model = ImageRequest.Builder(LocalContext.current) - .data(Images[index]) - .size(Size.ORIGINAL) - .build() - ) - if (painter.state is AsyncImagePainter.State.Success) { - val size = painter.intrinsicSize - Image( - painter = painter, - contentDescription = null, - modifier = Modifier - .aspectRatio(size.width / size.height) - .fillMaxSize() - ) - } - } - } - } + ZoomableAppWithPager() } diff --git a/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.kt b/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.kt deleted file mode 100644 index 3c52d15..0000000 --- a/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.mxalbert.zoomable.sample - -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.runtime.Composable -import androidx.compose.runtime.NonRestartableComposable - -@get:Composable -@get:NonRestartableComposable -internal expect val WindowInsets.Companion.safeDrawing: WindowInsets diff --git a/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.kt b/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.kt index 8934521..f098d7b 100644 --- a/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.kt +++ b/sample/shared/src/commonMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.kt @@ -5,6 +5,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -12,11 +13,15 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.selection.toggleable import androidx.compose.material.Button import androidx.compose.material.Checkbox @@ -28,8 +33,10 @@ import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.darkColors import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue @@ -39,13 +46,44 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp +import coil3.compose.AsyncImagePainter +import coil3.compose.LocalPlatformContext +import coil3.compose.rememberAsyncImagePainter +import coil3.request.ImageRequest +import coil3.size.Size import com.mxalbert.zoomable.OverZoomConfig import com.mxalbert.zoomable.Zoomable import com.mxalbert.zoomable.rememberZoomableState import kotlinx.coroutines.launch @Composable -internal fun ZoomableApp( +internal fun ZoomableAppWithPager() { + val snackbarHostState = remember { SnackbarHostState() } + + ZoomableApp(snackbarHostState = snackbarHostState) { + HorizontalPager(state = rememberPagerState { Images.size }) { index -> + ZoomableImagePage( + imageUrl = Images[index], + snackbarHostState = snackbarHostState + ) + } + } +} + +@Composable +internal fun ZoomableAppWithoutPager() { + val snackbarHostState = remember { SnackbarHostState() } + + ZoomableApp(snackbarHostState = snackbarHostState) { + ZoomableImagePage( + imageUrl = Images[0], + snackbarHostState = snackbarHostState + ) + } +} + +@Composable +private fun ZoomableApp( snackbarHostState: SnackbarHostState, modifier: Modifier = Modifier, content: @Composable () -> Unit @@ -72,10 +110,10 @@ internal fun ZoomableApp( } @Composable -internal fun ZoomableImagePage( +private fun ZoomableImagePage( + imageUrl: String, snackbarHostState: SnackbarHostState, - modifier: Modifier = Modifier, - image: @Composable () -> Unit + modifier: Modifier = Modifier ) { val scope = rememberCoroutineScope() var enabled by rememberSaveable { mutableStateOf(true) } @@ -103,9 +141,25 @@ internal fun ZoomableImagePage( snackbarHostState.showSnackbar("Dismissed.") } false - }, - content = image - ) + } + ) { + val painter = rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalPlatformContext.current) + .data(imageUrl) + .size(Size.ORIGINAL) + .build() + ) + if (painter.state.collectAsState().value is AsyncImagePainter.State.Success) { + val size = painter.intrinsicSize + Image( + painter = painter, + contentDescription = null, + modifier = Modifier + .aspectRatio(size.width / size.height) + .fillMaxSize() + ) + } + } AnimatedVisibility( visible = isOverlayVisible, diff --git a/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.desktop.kt b/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.desktop.kt deleted file mode 100644 index 3e9074e..0000000 --- a/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.desktop.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mxalbert.zoomable.sample - -import io.ktor.client.HttpClient -import io.ktor.client.engine.java.Java - -internal actual val httpClient = HttpClient(Java) diff --git a/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.desktop.kt b/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.desktop.kt index f8f8e40..845cd8e 100644 --- a/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.desktop.kt +++ b/sample/shared/src/desktopMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.desktop.kt @@ -1,16 +1,8 @@ package com.mxalbert.zoomable.sample -import androidx.compose.material.SnackbarHostState import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember @Composable fun ZoomableApp() { - val snackbarHostState = remember { SnackbarHostState() } - - ZoomableApp(snackbarHostState = snackbarHostState) { - ZoomableImagePage(snackbarHostState = snackbarHostState) { - AsyncZoomableImage(url = Images[0]) - } - } + ZoomableAppWithoutPager() } diff --git a/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.ios.kt b/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.ios.kt deleted file mode 100644 index 1d5b9d6..0000000 --- a/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.ios.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mxalbert.zoomable.sample - -import io.ktor.client.HttpClient -import io.ktor.client.engine.darwin.Darwin - -internal actual val httpClient = HttpClient(Darwin) diff --git a/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.ios.kt b/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.ios.kt deleted file mode 100644 index 56dc1ba..0000000 --- a/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.ios.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.mxalbert.zoomable.sample - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.pager.HorizontalPager -import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.material.SnackbarHostState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember - -@OptIn(ExperimentalFoundationApi::class) -@Composable -internal fun ZoomableApp() { - val snackbarHostState = remember { SnackbarHostState() } - - ZoomableApp(snackbarHostState = snackbarHostState) { - HorizontalPager(state = rememberPagerState { Images.size }) { index -> - ZoomableImagePage(snackbarHostState = snackbarHostState) { - AsyncZoomableImage(url = Images[index]) - } - } - } -} diff --git a/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/main.ios.kt b/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/main.ios.kt index e063901..e7830e0 100644 --- a/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/main.ios.kt +++ b/sample/shared/src/iosMain/kotlin/com/mxalbert/zoomable/sample/main.ios.kt @@ -1,27 +1,7 @@ package com.mxalbert.zoomable.sample -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.unit.dp import androidx.compose.ui.window.ComposeUIViewController -import kotlinx.cinterop.ExperimentalForeignApi -import kotlinx.cinterop.useContents -import platform.UIKit.UIApplication -import platform.UIKit.UIEdgeInsets -@OptIn(ExperimentalForeignApi::class) fun MainViewController() = ComposeUIViewController { - val insets = UIApplication.sharedApplication.keyWindow - ?.safeAreaInsets?.useContents { toWindowInsets() } - ?: LocalWindowInsets.current - CompositionLocalProvider(LocalWindowInsets provides insets) { - ZoomableApp() - } + ZoomableAppWithPager() } - -private fun UIEdgeInsets.toWindowInsets(): WindowInsets = WindowInsets( - left = left.dp, - top = top.dp, - right = right.dp, - bottom = bottom.dp -) diff --git a/sample/shared/src/nonAndroidMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.kt b/sample/shared/src/nonAndroidMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.kt deleted file mode 100644 index 119707f..0000000 --- a/sample/shared/src/nonAndroidMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.mxalbert.zoomable.sample - -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.produceState -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.painter.BitmapPainter -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.graphics.toComposeImageBitmap -import io.ktor.client.HttpClient -import io.ktor.client.request.get -import io.ktor.client.statement.readBytes -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.jetbrains.skia.Image - -private val imageCache: MutableMap = HashMap() - -internal expect val httpClient: HttpClient - -private suspend fun loadImage(url: String): ImageBitmap? { - imageCache[url]?.let { return it } - return withContext(Dispatchers.Default) { - runCatching { - Image.makeFromEncoded(httpClient.get(url).readBytes()).toComposeImageBitmap() - }.getOrNull()?.also { imageCache[url] = it } - } -} - -@Composable -internal fun AsyncZoomableImage(url: String) { - val painter by produceState(null, url) { - value = null - loadImage(url)?.let { value = BitmapPainter(it) } - } - painter?.let { - val size = it.intrinsicSize - Image( - painter = it, - contentDescription = null, - modifier = Modifier - .aspectRatio(size.width / size.height) - .fillMaxSize() - ) - } -} diff --git a/sample/shared/src/nonAndroidMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.nonAndroid.kt b/sample/shared/src/nonAndroidMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.nonAndroid.kt deleted file mode 100644 index 523497f..0000000 --- a/sample/shared/src/nonAndroidMain/kotlin/com/mxalbert/zoomable/sample/WindowInsets.nonAndroid.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.mxalbert.zoomable.sample - -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.runtime.Composable -import androidx.compose.runtime.NonRestartableComposable -import androidx.compose.runtime.compositionLocalOf - -internal val LocalWindowInsets = compositionLocalOf { - WindowInsets(0, 0, 0, 0) -} - -internal actual val WindowInsets.Companion.safeDrawing: WindowInsets - @Composable - @NonRestartableComposable - get() = LocalWindowInsets.current diff --git a/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.wasm.kt b/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.wasm.kt deleted file mode 100644 index e46ad69..0000000 --- a/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/AsyncZoomableImage.wasm.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.mxalbert.zoomable.sample - -import io.ktor.client.HttpClient -import io.ktor.client.engine.js.Js - -internal actual val httpClient = HttpClient(Js) diff --git a/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.wasm.kt b/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.wasm.kt index f8f8e40..845cd8e 100644 --- a/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.wasm.kt +++ b/sample/shared/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/ZoomableApp.wasm.kt @@ -1,16 +1,8 @@ package com.mxalbert.zoomable.sample -import androidx.compose.material.SnackbarHostState import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember @Composable fun ZoomableApp() { - val snackbarHostState = remember { SnackbarHostState() } - - ZoomableApp(snackbarHostState = snackbarHostState) { - ZoomableImagePage(snackbarHostState = snackbarHostState) { - AsyncZoomableImage(url = Images[0]) - } - } + ZoomableAppWithoutPager() } diff --git a/sample/wasmJsApp/src/wasmJsMain/kotlin/main.kt b/sample/wasmJsApp/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/main.kt similarity index 79% rename from sample/wasmJsApp/src/wasmJsMain/kotlin/main.kt rename to sample/wasmJsApp/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/main.kt index 5004403..88ec0a7 100644 --- a/sample/wasmJsApp/src/wasmJsMain/kotlin/main.kt +++ b/sample/wasmJsApp/src/wasmJsMain/kotlin/com/mxalbert/zoomable/sample/main.kt @@ -1,8 +1,7 @@ -package com.github.trueddd +package com.mxalbert.zoomable.sample import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.window.CanvasBasedWindow -import com.mxalbert.zoomable.sample.ZoomableApp @OptIn(ExperimentalComposeUiApi::class) fun main() { diff --git a/zoomable/build.gradle.kts b/zoomable/build.gradle.kts index 9ef7a1a..f586e60 100644 --- a/zoomable/build.gradle.kts +++ b/zoomable/build.gradle.kts @@ -1,7 +1,6 @@ import com.vanniktech.maven.publish.JavadocJar import com.vanniktech.maven.publish.KotlinMultiplatform import com.vanniktech.maven.publish.SonatypeHost -import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.dsl.JvmTarget @@ -20,7 +19,6 @@ kotlin { androidTarget { publishLibraryVariants("release") - @OptIn(ExperimentalKotlinGradlePluginApi::class) compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) } @@ -71,9 +69,9 @@ kotlin { } wasmJsMain.dependencies { - implementation(libs.compose.runtime.jetbrains) - implementation(libs.compose.foundation.jetbrains) - implementation(libs.compose.ui.util.jetbrains) + api(libs.compose.runtime.jetbrains) + api(libs.compose.foundation.jetbrains) + api(libs.compose.ui.util.jetbrains) } } } @@ -107,7 +105,7 @@ mavenPublishing { publishToMavenCentral(SonatypeHost.S01) signAllPublications() pomFromGradleProperties() - configure(KotlinMultiplatform(JavadocJar.Dokka("dokkaHtml"))) + configure(KotlinMultiplatform(JavadocJar.Dokka("dokkaGenerate"))) } publishing {