@@ -361,6 +361,7 @@ pub async fn get_available_skins() -> crate::Result<Vec<Skin>> {
361361 ) ;
362362 let mut found_equipped_skin = false ;
363363 let mut available_skins = Vec :: new ( ) ;
364+ let mut custom_skins = Vec :: new ( ) ;
364365 let mut saved_default_skins = Vec :: new ( ) ;
365366
366367 for mut custom_skin in CustomMinecraftSkin :: get_all ( profile. id , & state. pool )
@@ -426,7 +427,7 @@ pub async fn get_available_skins() -> crate::Result<Vec<Skin>> {
426427 None => custom_skin. texture_blob ( & state. pool ) . await ?,
427428 } ;
428429
429- available_skins . push ( Skin {
430+ custom_skins . push ( Skin {
430431 name : None ,
431432 section : None ,
432433 variant : custom_skin. variant ,
@@ -444,6 +445,9 @@ pub async fn get_available_skins() -> crate::Result<Vec<Skin>> {
444445 } ) ;
445446 }
446447
448+ custom_skins. sort_by ( |a, b| a. texture . as_str ( ) . cmp ( b. texture . as_str ( ) ) ) ;
449+ available_skins. extend ( custom_skins) ;
450+
447451 for default_skin in assets:: DEFAULT_SKINS . iter ( ) {
448452 let is_equipped = !found_equipped_skin
449453 && default_skin. texture_key == current_skin_texture_key
@@ -676,9 +680,17 @@ async fn equip_skin_now(
676680
677681 preserve_current_profile_skin ( & state, & profile) . await ?;
678682
683+ let texture_blob = png_util:: url_to_data_stream ( & skin. texture )
684+ . await ?
685+ . try_fold ( Vec :: new ( ) , |mut texture, chunk| async move {
686+ texture. extend_from_slice ( & chunk) ;
687+ Ok ( texture)
688+ } )
689+ . await ?;
690+
679691 let profile = mojang_api:: MinecraftSkinOperation :: equip (
680692 selected_credentials,
681- png_util :: url_to_data_stream ( & skin . texture ) . await ? ,
693+ stream :: iter ( [ Ok :: < _ , String > ( Bytes :: from ( texture_blob . clone ( ) ) ) ] ) ,
682694 skin. variant ,
683695 )
684696 . await ?;
@@ -693,6 +705,13 @@ async fn equip_skin_now(
693705 } ) ?,
694706 } ;
695707
708+ if let Err ( error) =
709+ persist_equipped_skin ( & state, & profile, skin, & texture_blob) . await
710+ {
711+ refresh_profile_cache ( selected_credentials) . await ;
712+ return Err ( error) ;
713+ }
714+
696715 if let Err ( error) =
697716 sync_cape ( selected_credentials, & profile, skin. cape_id ) . await
698717 {
@@ -703,6 +722,54 @@ async fn equip_skin_now(
703722 Ok ( ( ) )
704723}
705724
725+ async fn persist_equipped_skin (
726+ state : & State ,
727+ profile : & MinecraftProfile ,
728+ skin : & Skin ,
729+ texture_blob : & [ u8 ] ,
730+ ) -> crate :: Result < ( ) > {
731+ let equipped_skin = profile. current_skin ( ) ?;
732+ let equipped_skin_texture_key = equipped_skin. texture_key ( ) ;
733+ let equipped_skin_variant = equipped_skin. variant ;
734+ let texture_key_changed =
735+ skin. texture_key . as_ref ( ) != equipped_skin_texture_key. as_ref ( ) ;
736+
737+ if skin. cape_id . is_none ( )
738+ && is_bundled_skin ( & equipped_skin_texture_key, equipped_skin_variant)
739+ {
740+ CustomMinecraftSkin {
741+ texture_key : equipped_skin_texture_key. to_string ( ) ,
742+ variant : equipped_skin_variant,
743+ cape_id : None ,
744+ }
745+ . remove ( profile. id , & state. pool )
746+ . await ?;
747+ } else if texture_key_changed || !matches ! ( & skin. source, SkinSource :: Custom )
748+ {
749+ CustomMinecraftSkin :: add (
750+ profile. id ,
751+ & equipped_skin_texture_key,
752+ texture_blob,
753+ equipped_skin_variant,
754+ skin. cape_id ,
755+ & state. pool ,
756+ )
757+ . await ?;
758+ }
759+
760+ if texture_key_changed {
761+ CustomMinecraftSkin {
762+ texture_key : skin. texture_key . to_string ( ) ,
763+ variant : skin. variant ,
764+ cape_id : skin. cape_id ,
765+ }
766+ . remove ( profile. id , & state. pool )
767+ . await ?;
768+ }
769+
770+ Ok ( ( ) )
771+ }
772+
706773/// Removes a custom skin from the app database.
707774///
708775/// The player will continue to be equipped with the same skin and cape as before, even if
0 commit comments