diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 0b37c7fff..38d2a4787 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -416,6 +416,7 @@ kotlin { implementation(libs.compose.ui) implementation(libs.compose.components.resources) implementation(libs.compose.uiToolingPreview) + implementation(libs.compottie) implementation(libs.androidx.lifecycle.viewmodelCompose) implementation(libs.androidx.lifecycle.runtimeCompose) implementation(libs.kotlinx.serialization.json) diff --git a/composeApp/src/commonMain/composeResources/files/nuvio_loading_indicator.json b/composeApp/src/commonMain/composeResources/files/nuvio_loading_indicator.json new file mode 100644 index 000000000..afc53d401 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/files/nuvio_loading_indicator.json @@ -0,0 +1 @@ +{"nm":"ios-spinner","ddd":0,"h":600,"w":600,"meta":{"g":"@lottiefiles/toolkit-js 0.33.2"},"layers":[{"ty":4,"nm":"1","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-180,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"s":[0],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"2","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-150,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[8],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":4},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":5},{"s":[8],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2},{"ty":4,"nm":"3","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-120,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[16],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":9},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":10},{"s":[16],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3},{"ty":4,"nm":"4","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-90,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[24],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":14},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":15},{"s":[24],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":4},{"ty":4,"nm":"5","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-60,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[32],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":19},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":20},{"s":[32],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":5},{"ty":4,"nm":"6","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-30,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[40],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":24},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":25},{"s":[40],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":6},{"ty":4,"nm":"7","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[48],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":29},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":30},{"s":[48],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":7},{"ty":4,"nm":"8","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-330,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[56],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":34},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":35},{"s":[56],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":8},{"ty":4,"nm":"9","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-300,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[64],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":39},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":40},{"s":[64],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":9},{"ty":4,"nm":"10","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-270,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[72],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":44},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":45},{"s":[72],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":10},{"ty":4,"nm":"11","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-240,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[80],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":49},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":50},{"s":[80],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":11},{"ty":4,"nm":"12","sr":1,"st":0,"op":61,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[300,300,0],"ix":2},"r":{"a":0,"k":-210,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[88],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":54},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":55},{"s":[88],"t":60}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Shape 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13,22],[13,124]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"c":{"a":0,"k":[0,0,0],"ix":3}},{"ty":"tr","a":{"a":0,"k":[11,-82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":12}],"v":"5.7.5","fr":60,"op":61,"ip":0,"assets":[]} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt index d26d922d5..49829fd1a 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt @@ -28,7 +28,7 @@ import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Home -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -585,7 +585,7 @@ fun App() { .background(MaterialTheme.nuvio.colors.background), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator(color = MaterialTheme.nuvio.colors.accent) + NuvioLoadingIndicator(color = MaterialTheme.nuvio.colors.accent) } } AppGateScreen.Auth.name -> { @@ -2224,7 +2224,7 @@ private fun MainAppContent( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator(color = MaterialTheme.nuvio.colors.accent) + NuvioLoadingIndicator(color = MaterialTheme.nuvio.colors.accent) } return@composable } @@ -2437,7 +2437,7 @@ private fun MainAppContent( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(MaterialTheme.nuvio.spacing.cardPadding), ) { - CircularProgressIndicator(color = MaterialTheme.nuvio.colors.playerControlsForeground) + NuvioLoadingIndicator(color = MaterialTheme.nuvio.colors.playerControlsForeground) Text( text = stringResource(Res.string.streams_finding_source), color = MaterialTheme.nuvio.colors.playerControlsForeground.copy(alpha = MaterialTheme.nuvio.opacity.overlayHeavy), @@ -3297,7 +3297,7 @@ private fun AppLaunchOverlay( contentScale = ContentScale.Fit, ) Spacer(modifier = Modifier.height(tokens.spacing.sectionGap)) - CircularProgressIndicator(color = tokens.colors.accent) + NuvioLoadingIndicator(color = tokens.colors.accent) } } } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/Components.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/Components.kt index 7b0be071b..3f5eefd5a 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/Components.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/Components.kt @@ -35,7 +35,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -431,9 +430,8 @@ fun NuvioStatusModal( modifier = Modifier.padding(tokens.spacing.dialogPadding), ) { if (isBusy) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = tokens.colors.accent, - strokeWidth = NuvioTokens.Border.medium + NuvioTokens.Space.hairline, ) Spacer(modifier = Modifier.height(NuvioTokens.Space.s16)) } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/LoadingIndicator.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/LoadingIndicator.kt new file mode 100644 index 000000000..d1c282bd8 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/LoadingIndicator.kt @@ -0,0 +1,57 @@ +package com.nuvio.app.core.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.size +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.unit.Dp +import io.github.alexzhirkevich.compottie.Compottie +import io.github.alexzhirkevich.compottie.LottieCompositionSpec +import io.github.alexzhirkevich.compottie.animateLottieCompositionAsState +import io.github.alexzhirkevich.compottie.rememberLottieComposition +import io.github.alexzhirkevich.compottie.rememberLottiePainter +import nuvio.composeapp.generated.resources.Res + +@Composable +fun NuvioLoadingIndicator( + modifier: Modifier = Modifier, + color: Color = MaterialTheme.nuvio.colors.textSecondary, + size: Dp = NuvioTokens.Space.s40, +) { + Box( + modifier = modifier.size(size), + contentAlignment = Alignment.Center, + ) { + val composition by rememberLottieComposition { + LottieCompositionSpec.JsonString( + Res.readBytes("files/nuvio_loading_indicator.json").decodeToString() + ) + } + val progress by animateLottieCompositionAsState( + composition = composition, + iterations = Compottie.IterateForever, + ) + + Image( + painter = rememberLottiePainter( + composition = composition, + progress = { progress }, + ), + contentDescription = null, + colorFilter = ColorFilter.tint(color), + modifier = Modifier + .fillMaxSize() + .graphicsLayer { + clip = false + }, + ) + } +} diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/TraktListPickerDialog.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/TraktListPickerDialog.kt index a9894b30b..155661350 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/TraktListPickerDialog.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/ui/TraktListPickerDialog.kt @@ -18,7 +18,6 @@ import androidx.compose.material.icons.rounded.Check import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -92,8 +91,7 @@ fun TraktListPickerDialog( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(tokens.spacing.listGap), ) { - CircularProgressIndicator( - strokeWidth = tokens.borders.medium, + NuvioLoadingIndicator( modifier = Modifier.size(tokens.icons.lg), ) Text( @@ -164,9 +162,8 @@ fun TraktListPickerDialog( enabled = !isPending, ) { if (isPending) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = tokens.colors.onAccent, - strokeWidth = tokens.borders.medium, modifier = Modifier.size(tokens.icons.sm), ) } else { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/auth/AuthScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/auth/AuthScreen.kt index 025fb3fee..b0d3167cf 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/auth/AuthScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/auth/AuthScreen.kt @@ -42,7 +42,7 @@ import androidx.compose.material.icons.rounded.Visibility import androidx.compose.material.icons.rounded.VisibilityOff import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -872,10 +872,9 @@ private fun AuthPrimaryButton( ), ) { if (isLoading) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(20.dp * scale), color = AuthPrimaryButtonText, - strokeWidth = 2.dp * scale, ) } else { Text( diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt index 31ac63abd..87cb0f0fd 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt @@ -19,7 +19,7 @@ import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -379,10 +379,9 @@ private fun CatalogLoadingFooter() { .padding(vertical = 12.dp), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(22.dp), color = MaterialTheme.colorScheme.primary, - strokeWidth = 2.dp, ) } } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt index 5881ce2e4..11ba0a6c9 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt @@ -23,7 +23,7 @@ import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.items import androidx.compose.material3.LocalRippleConfiguration -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ScrollableTabRow import androidx.compose.material3.Tab @@ -370,10 +370,9 @@ private fun PaginationLoadingFooter() { .padding(vertical = 8.dp), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(28.dp), color = MaterialTheme.colorScheme.primary, - strokeWidth = 3.dp, ) } } @@ -393,10 +392,9 @@ private fun LoadingIndicator() { modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(32.dp), color = MaterialTheme.colorScheme.primary, - strokeWidth = 3.dp, ) } } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt index e811ad8b1..f3b9555ef 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt @@ -36,7 +36,7 @@ import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.CheckCircleOutline import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -310,7 +310,7 @@ fun MetaDetailsScreen( ) { when { displayedMeta == null && uiState.isLoading -> { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.align(Alignment.Center), color = MaterialTheme.colorScheme.primary, ) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/TrailerPlayerPopup.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/TrailerPlayerPopup.kt index 09976eba1..5cb22bf37 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/TrailerPlayerPopup.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/TrailerPlayerPopup.kt @@ -12,7 +12,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.Icons -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -140,7 +140,7 @@ fun TrailerPlayerPopup( ) { when { isLoading -> { - CircularProgressIndicator(color = MaterialTheme.colorScheme.primary) + NuvioLoadingIndicator(color = MaterialTheme.colorScheme.primary) } activeError != null -> { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryScreen.kt index bd8893bba..9e29c5776 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryScreen.kt @@ -30,7 +30,7 @@ import androidx.compose.material.icons.automirrored.filled.InsertDriveFile import androidx.compose.material.icons.automirrored.rounded.ArrowBack import androidx.compose.material.icons.rounded.PlayArrow import androidx.compose.material.icons.rounded.Refresh -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LinearProgressIndicator @@ -591,9 +591,8 @@ private fun LibraryChip( horizontalArrangement = Arrangement.spacedBy(6.dp), ) { if (loading) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(12.dp), - strokeWidth = 1.5.dp, color = colorScheme.primary, ) } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt index c3cc400b3..d79510317 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt @@ -34,7 +34,7 @@ import androidx.compose.material.icons.rounded.Replay10 import androidx.compose.material.icons.rounded.Speed import androidx.compose.material.icons.rounded.SwapHoriz import androidx.compose.material.icons.rounded.VideoLibrary -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider @@ -463,9 +463,8 @@ private fun PlayPauseControlButton( contentAlignment = Alignment.Center, ) { if (isBuffering) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = Color.White, - strokeWidth = 3.dp, modifier = Modifier.size(metrics.playIconSize), ) } else { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerEpisodesPanel.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerEpisodesPanel.kt index ee13781b6..74e3cfe2e 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerEpisodesPanel.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerEpisodesPanel.kt @@ -32,7 +32,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.rounded.ArrowBack import androidx.compose.material.icons.rounded.Refresh -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -576,9 +576,8 @@ private fun EpisodeStreamsSubView( .padding(vertical = NuvioTokens.Space.s40), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = tokens.colors.accent, - strokeWidth = tokens.borders.medium, modifier = Modifier.size(tokens.icons.lg + NuvioTokens.Space.s4), ) } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerOverlays.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerOverlays.kt index 6ff03c858..d3ae9b4b4 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerOverlays.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerOverlays.kt @@ -40,7 +40,7 @@ import androidx.compose.material.icons.rounded.ErrorOutline import androidx.compose.material.icons.rounded.FastForward import androidx.compose.material.icons.rounded.FastRewind import androidx.compose.material.icons.rounded.Speed -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -238,9 +238,8 @@ internal fun OpeningOverlay( }, ) } else { - CircularProgressIndicator( + NuvioLoadingIndicator( color = Color(0xFFE50914), - strokeWidth = 3.dp, modifier = Modifier.size(54.dp), ) } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSourcesPanel.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSourcesPanel.kt index 154482412..d3bafa5fa 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSourcesPanel.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSourcesPanel.kt @@ -26,7 +26,7 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Refresh -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -176,9 +176,8 @@ fun PlayerSourcesPanel( .padding(vertical = NuvioTokens.Space.s40), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = tokens.colors.accent, - strokeWidth = tokens.borders.medium, modifier = Modifier.size(tokens.icons.lg + NuvioTokens.Space.s4), ) } @@ -272,9 +271,8 @@ internal fun AddonFilterChip( horizontalArrangement = Arrangement.spacedBy(NuvioTokens.Space.s6), ) { if (isLoading) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = tokens.colors.accent, - strokeWidth = tokens.borders.thin + NuvioTokens.Space.hairline, modifier = Modifier.size(NuvioTokens.Icon.xs), ) } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/SubtitleModal.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/SubtitleModal.kt index 415f2e2db..2671b0ba1 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/SubtitleModal.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/SubtitleModal.kt @@ -29,7 +29,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Check import androidx.compose.material.icons.rounded.CloudDownload -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -317,9 +317,8 @@ private fun AddonSubtitleList( .padding(40.dp), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = colorScheme.primary, - strokeWidth = 2.dp, modifier = Modifier.size(32.dp), ) } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt index 8be4314e4..b173d239a 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt @@ -28,7 +28,7 @@ import androidx.compose.material.icons.rounded.Replay import androidx.compose.material.icons.rounded.Send import androidx.compose.material.icons.rounded.StopCircle import androidx.compose.material3.BasicAlertDialog -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -228,10 +228,9 @@ fun SubmitIntroDialog( contentAlignment = Alignment.Center ) { if (isSubmitting) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = MaterialTheme.colorScheme.onPrimary, modifier = Modifier.size(24.dp), - strokeWidth = 2.dp ) } else { Row( diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/search/SearchDiscoverContent.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/search/SearchDiscoverContent.kt index 21da5ce14..57d7a5883 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/search/SearchDiscoverContent.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/search/SearchDiscoverContent.kt @@ -18,7 +18,7 @@ import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -319,10 +319,9 @@ private fun CatalogLoadingFooter(modifier: Modifier = Modifier) { .padding(vertical = 8.dp), contentAlignment = Alignment.Center, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(22.dp), color = MaterialTheme.colorScheme.primary, - strokeWidth = 2.dp, ) } } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/DebridSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/DebridSettingsPage.kt index 777293c00..5452420f4 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/DebridSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/DebridSettingsPage.kt @@ -23,7 +23,7 @@ import androidx.compose.material.icons.rounded.Visibility import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button import androidx.compose.material3.Checkbox -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -1585,7 +1585,7 @@ private fun DebridDeviceAuthDialog( horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically, ) { - CircularProgressIndicator(strokeWidth = 2.dp, modifier = Modifier.size(18.dp)) + NuvioLoadingIndicator(modifier = Modifier.size(18.dp)) Text( text = startingMessage, style = MaterialTheme.typography.bodyMedium, @@ -1633,7 +1633,7 @@ private fun DebridDeviceAuthDialog( verticalAlignment = Alignment.CenterVertically, ) { if (isPolling) { - CircularProgressIndicator(strokeWidth = 2.dp, modifier = Modifier.size(16.dp)) + NuvioLoadingIndicator(modifier = Modifier.size(16.dp)) } Text( text = message, diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt index e9ed0e6ef..f95eeb503 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt @@ -24,7 +24,7 @@ import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Check import androidx.compose.material3.BasicAlertDialog -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -3302,9 +3302,8 @@ private fun IntroDbApiKeyDialog( enabled = !isVerifying ) { if (isVerifying) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(16.dp), - strokeWidth = 2.dp, color = MaterialTheme.colorScheme.primary ) } else { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt index 38117df1d..360d492a7 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/StreamsSettingsPage.kt @@ -21,7 +21,7 @@ import androidx.compose.material.icons.rounded.Delete import androidx.compose.material.icons.rounded.Visibility import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -306,8 +306,7 @@ private fun BadgeUrlManagerDialog( }, ) { if (isImporting) { - CircularProgressIndicator( - strokeWidth = tokens.borders.medium, + NuvioLoadingIndicator( modifier = Modifier.size(tokens.icons.sm), color = tokens.colors.onAccent, ) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SupportersContributorsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SupportersContributorsPage.kt index 6ff9426a0..84074daaf 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SupportersContributorsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SupportersContributorsPage.kt @@ -27,7 +27,7 @@ import androidx.compose.material.icons.rounded.Favorite import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.LinearProgressIndicator @@ -858,7 +858,7 @@ private fun LoadingState( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - CircularProgressIndicator(strokeWidth = 2.dp) + NuvioLoadingIndicator() Text( text = label, style = MaterialTheme.typography.bodyMedium, diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TraktSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TraktSettingsPage.kt index ac9815580..6d314e07a 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TraktSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TraktSettingsPage.kt @@ -18,7 +18,7 @@ import androidx.compose.material.icons.rounded.Check import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -704,9 +704,8 @@ private fun TraktConnectionCard( ), ) { if (uiState.isLoading) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = MaterialTheme.colorScheme.onSurface, - strokeWidth = 2.dp, modifier = Modifier.size(18.dp), ) } else { @@ -774,9 +773,8 @@ private fun TraktConnectionCard( enabled = uiState.credentialsConfigured && !uiState.isLoading, ) { if (uiState.isLoading) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 2.dp, modifier = Modifier.size(18.dp), ) } else { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt index 454a8dbd9..f7176ef77 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt @@ -43,7 +43,7 @@ import androidx.compose.material.icons.rounded.ContentCopy import androidx.compose.material.icons.rounded.Download import androidx.compose.material.icons.rounded.Refresh import androidx.compose.material.icons.rounded.SearchOff -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -336,10 +336,9 @@ fun StreamsScreen( modifier = Modifier.padding(horizontal = 24.dp), ) } - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(32.dp), color = Color.White, - strokeWidth = 2.5.dp, ) Text( text = uiState.overlayMessage @@ -1048,9 +1047,8 @@ private fun StreamSectionHeader( ) AnimatedVisibility(visible = isLoading, enter = fadeIn(), exit = fadeOut()) { Row(verticalAlignment = Alignment.CenterVertically) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(12.dp), - strokeWidth = 1.5.dp, color = MaterialTheme.colorScheme.primary, ) Spacer(modifier = Modifier.width(6.dp)) @@ -1214,7 +1212,7 @@ private fun LoadingStateBlock(modifier: Modifier = Modifier) { horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - CircularProgressIndicator( + NuvioLoadingIndicator( color = MaterialTheme.colorScheme.primary, modifier = Modifier.size(32.dp), ) @@ -1299,9 +1297,8 @@ private fun FooterLoadingBlock(modifier: Modifier = Modifier) { horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(14.dp), - strokeWidth = 2.dp, color = MaterialTheme.colorScheme.primary, ) Spacer(modifier = Modifier.width(8.dp)) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/updater/AppUpdater.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/updater/AppUpdater.kt index 75427d6a4..6cfe92451 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/updater/AppUpdater.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/updater/AppUpdater.kt @@ -15,7 +15,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.Button -import androidx.compose.material3.CircularProgressIndicator +import com.nuvio.app.core.ui.NuvioLoadingIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme @@ -488,9 +488,8 @@ fun AppUpdaterHost( verticalAlignment = Alignment.CenterVertically, ) { if (state.isChecking) { - CircularProgressIndicator( + NuvioLoadingIndicator( modifier = Modifier.size(18.dp), - strokeWidth = 2.dp, ) Spacer(modifier = Modifier.width(10.dp)) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 949d47262..2515c3f50 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ androidx-work = "2.10.3" androidx-testExt = "1.3.0" composeMultiplatform = "1.11.1" coil = "3.5.0-beta01" +compottie = "2.1.0" kermit = "2.0.5" junit = "4.13.2" kotlin = "2.3.0" @@ -54,6 +55,7 @@ compose-material3 = { module = "org.jetbrains.compose.material3:material3", vers compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" } compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeMultiplatform" } compose-uiToolingPreview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "composeMultiplatform" } +compottie = { module = "io.github.alexzhirkevich:compottie", version.ref = "compottie" } coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" } coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" }