feat: Add Launcher icons and begin work on importing instances
5
.vscode/settings.json
vendored
|
|
@ -188,6 +188,7 @@
|
|||
"*.vue": "$(capture).*.ts, $(capture).*.js, $(capture).story.vue",
|
||||
"*.w": "$(capture).*.w, I$(capture).w",
|
||||
"*.xaml": "$(capture).xaml.cs"
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"svg.preview.background": "editor"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ macro_rules! collect_commands {
|
|||
// Metadata
|
||||
get_minecraft_versions,
|
||||
// Launcher Packages (Instances)
|
||||
import_launcher_instances,
|
||||
get_launcher_instances,
|
||||
import_instances,
|
||||
// Provider Packages
|
||||
get_provider_package,
|
||||
get_provider_packages,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
|||
use onelauncher::cluster::content::package;
|
||||
use onelauncher::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion, PackageType};
|
||||
use onelauncher::package::content::Providers;
|
||||
use onelauncher::package::import::{default_launcher_path, ImportType};
|
||||
use onelauncher::package::import::ImportType;
|
||||
use onelauncher::store::{
|
||||
Author, ClusterPath, Package, PackageBody, PackagePath, ProviderSearchResults,
|
||||
};
|
||||
|
|
@ -12,18 +12,25 @@ use uuid::Uuid;
|
|||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn import_launcher_instances(
|
||||
pub async fn get_launcher_instances(
|
||||
launcher: ImportType,
|
||||
path: Option<PathBuf>,
|
||||
) -> Result<(String, Vec<String>), String> {
|
||||
let (dir, instances) = onelauncher::api::package::import::get_launcher_instances(launcher, path).await?;
|
||||
Ok((
|
||||
dir.to_str().ok_or("could not convert pathbuf to string")?.to_string(),
|
||||
instances
|
||||
))
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn import_instances(
|
||||
launcher: ImportType,
|
||||
base_path: PathBuf,
|
||||
instances: Vec<String>,
|
||||
) -> Result<(), String> {
|
||||
onelauncher::api::package::import::import_instances(
|
||||
launcher,
|
||||
path.unwrap_or(
|
||||
default_launcher_path(launcher)
|
||||
.ok_or("couldn't get a default path for this launcher")?,
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
onelauncher::api::package::import::import_instances(launcher, base_path, instances).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 53.5">
|
||||
<path fill="currentColor" fill-rule="evenodd"
|
||||
<path fill="#F16436" fill-rule="evenodd"
|
||||
d="M0 6.9082l27.9532.0756L26.269 0h73.7449l-.0164 8.1433C87.5 10.6348 78.6726 16.775 74.825 36.34H72.046l-1.5815 4.359h2.3079l3.9906 12.8087H37.961l3.9184-12.8086h2.325l-1.6467-4.359h-2.7642l-5.1516-13.7535C13.5203 21.3437 2.6748 16.9042 0 6.9082zM58.6772 39.062c-3.082-5.6216-5.1058-1.197-11.4454-6.9496-2.4727-2.2436-3.4588-8.8199 2.097-10.8301-2.5255 5.5749 4.0297 7.8558 5.5898 4.6685.709-1.4486 1.6039-4.1204-.9798-5.9518-1.392-.9867-1.9281-3.9125-.7364-5.5388.3837 1.2093 1.5938 2.5013 3.916 1.5411-4.9192-8.1404 2.934-10.9457 6.7104-10.5817-3.9686.441-6.025 3.977-4.2196 7.8269 1.15 2.452 2.9006 3.6589 3.4097 5.6657-1.6952.1263-2.1852.9065-2.1495 2.362.0268 1.0895 2.5496 2.6646 2.9494-.4456 1.175 2.4245-.2407 3.8496-1.0129 4.9984-1.7824 2.6515-.1036 5.4107 2.1097 3.3067.9547-.9074 1.6155-2.5812.4048-5.318 2.229 1.776 4.5057 6.5447.9079 10.677-1.756 2.017-6.9514 1.391-7.551 4.5693z" />
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1,022 B |
1
apps/frontend/src/assets/logos/launchers/atlauncher.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 2084 2084" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2"><g fill-rule="nonzero"><path d="M1041.67 81.38l272.437 159.032-825.246 478.685-272.438-157.971L1041.67 81.38zm87.28 371.074l274.024-159.032 463.937 271.945-276.14 153.73-461.821-266.643z" fill="#3b3b3b"/><path d="M216.42 561.126v961.081l825.247 479.746V1684.95l-551.222-321.774-1.587-644.079L216.42 561.126z" fill="#2e2e2e"/><path d="M1866.91 1517.97l-825.246 483.986v-317.003l550.164-320.714-1.058-645.139 276.14-153.73v952.6z" fill="#333"/><path d="M1590.77 719.097l-549.106 310.112v165.393l214.246-122.984v488.757l138.599-81.106V989.451l196.261-115.563V719.097z" fill="#89c236"/><path d="M488.858 719.097l1.587 644.079 152.353 90.118v-198.79l230.645 132.527v199.319l168.753 98.6v-655.741L488.858 719.097zm383.527 531.166l-227.471-131.466v-150.02l227.471 127.225v154.261z" fill="#7baf31"/></g></svg>
|
||||
|
After Width: | Height: | Size: 952 B |
1
apps/frontend/src/assets/logos/launchers/ftb.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1175 889"><path d="m1174.14 355.903-29.88-21.468 9.11-21.068V112.095L1033.12 0H117.189L.139 117.05v535.656l26.974 48.541H.14v187.46h1174v-187.46h-26.97l26.97-48.541V355.903ZM254.706 652.706V485.413h97.634l39.083-70.309V276.235h35.88v376.471l26.973 48.541H227.734l26.972-48.541Zm400.892 48.541 26.973-48.541V276.235h17.465v286.694l25.772 61.453 76.915 76.865H655.598Z" fill="#fff"/><path d="m1119.69 341.239 13.81-31.977V120.751L1025.31 19.865H125.395l-105.39 105.39V647.55l30.876 55.597h153.081l30.876-55.597V465.545h105.84l30.876-55.598v-153.58h75.565V647.55l30.876 55.597h153.781l30.876-55.597V256.367h57.199v302.557l22.669 54.146 90.127 90.077h290.743l30.88-55.597V366.06l-34.58-24.821Z" fill="#322A2A"/><path d="m185.249 433.77 17.815 205.525-17.815 32.077H69.6l-17.815-32.077L69.6 195.617l76.365-76.365h187.46l17.815 73.212-17.815 32.078H185.249v105.99h136.716l17.815 71.161-17.815 32.077H185.249Z" fill="#65ADB9"/><path d="M717.351 224.59H613.112l17.815 414.754-17.815 32.077H496.763l-17.815-32.077 17.815-414.754H388.671l-17.815-32.077 17.815-73.212h328.68l17.815 73.212-17.815 32.077Z" fill="#9FC41E"/><path d="m1104.68 441.374 17.82 197.969-17.82 32.077H845.761l-76.365-76.365-17.815-42.486 17.815-433.219h236.354l78.16 72.862 17.82 110.544-17.82 41.335-54.24 43.487 75.01 53.846v-.05ZM969.616 338.186V224.589h-84.522v113.597h84.522Zm18.716 228.595V441.424H885.144v125.357h103.188Z" fill="#E65014"/><path d="M51.785 138.419v500.927h151.279V401.744H339.78V262.925H203.064v-70.409H351.24V51.646H138.559l-86.774 86.773Z" fill="#0787C1"/><path d="M370.807 192.516h108.092v446.83h151.98v-446.83h104.289V51.646H370.807v140.87Z" fill="#798B2F"/><path d="m1059.14 336.838 42.59-34.179V134.566l-88.93-82.92H751.629v500.876l86.824 86.774h284.097V382.327l-63.36-45.539-.05.05ZM902.908 499.077V409.3h67.608v89.777h-67.608Zm0-228.595v-77.967H951.8v77.967h-48.892Z" fill="#B11917"/><path d="M185.246 383.927v237.602H69.598V145.774l76.365-76.365h187.459V174.7H185.246v105.99h136.717v103.188H185.246v.05ZM717.348 174.748H613.11v446.78H496.761v-446.78H388.668V69.458h328.68v105.29ZM1104.68 391.532v229.996H845.758l-76.365-76.365V69.458h236.347l78.17 72.862v151.829l-54.25 43.487 75.02 53.846v.05ZM969.614 288.344V174.748h-84.522v113.596h84.522Zm18.716 228.595V391.582H885.142v125.357H988.33Z" fill="#fff"/><path d="M1154.27 721.112H20.005v147.726H1154.27V721.112Z" fill="#322A2A"/><path d="M71.45 802.433v38.933H52.483v-77.967l12.511-12.51H95.72v17.214H71.45v17.465h22.419v16.915h-22.42v-.05ZM129.248 750.889h43.937v17.214h-25.171v17.465h23.92v16.915h-23.67v21.768h25.522v17.165h-44.538v-90.527ZM206.364 750.889h43.938v17.214H225.13v17.465h23.921v16.915H225.38v21.768h25.522v17.165h-44.538v-90.527ZM283.481 750.89h38.933l14.563 14.312v63.604l-12.711 12.511h-40.785V750.84v.05Zm34.479 73.312v-56.097h-15.513v56.097h15.513ZM478.849 768.103h-17.065v73.263h-19.066v-73.263h-17.715v-17.214h53.846v17.214ZM531.089 788.07h16.264v-37.181h18.966v90.477h-18.966v-36.181h-16.264v36.181h-18.966v-90.477h18.966v37.181ZM600.049 750.889h43.938v17.214h-25.172v17.465h23.921v16.915h-23.67v21.768h25.521v17.165h-44.538v-90.527ZM786.91 803.684v37.682h-42.436l-12.511-12.511v-77.966h38.783l12.811 11.96v24.921l-8.907 7.156 12.21 8.808.05-.05Zm-22.069-16.915v-18.716H750.93v18.716h13.911Zm3.053 37.432v-20.517H750.93v20.517h16.964ZM820.54 750.889h43.937v17.214h-25.171v17.465h23.92v16.915h-23.67v21.768h25.522v17.165H820.54v-90.527ZM916.668 841.365h-19.017V765.25l14.563-14.312h39.533v90.477h-18.966v-29.726h-16.164v29.726l.051-.05Zm16.163-46.94v-26.323h-16.163v26.323h16.163ZM1035.57 841.367h-49.743v-28.174h18.963v11.009h11.76V809.79l-30.072-22.719V750.84h48.542v26.923h-17.22v-9.658h-12.41v11.81l30.18 22.669V841.367ZM1123.25 768.103h-17.07v73.263h-19.07v-73.263h-17.71v-17.214h53.85v17.214Z" fill="#E0E0E0"/></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
BIN
apps/frontend/src/assets/logos/launchers/gdlauncher.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
apps/frontend/src/assets/logos/launchers/multimc.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
52
apps/frontend/src/assets/logos/launchers/prismlauncher.svg
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<svg width="48" height="48" version="1.1" viewBox="0 0 12.7 12.7" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<title>Prism Launcher Logo</title>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:title>Prism Launcher Logo</dc:title>
|
||||
<dc:date>19/10/2022</dc:date>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Prism Launcher</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>AutiOne, Boba, ely, Fulmine, gon sawa, Pankakes, tobimori, Zeke</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>Prism Launcher</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
|
||||
</cc:Work>
|
||||
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
|
||||
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
|
||||
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
|
||||
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g stroke-width=".26458">
|
||||
<g>
|
||||
<path d="m6.35 0.52917-2.5208 4.3656 2.5208 1.4552 2.5203-1.4552 0.10955-3.0996c-1.1511-0.66459-2.3388-1.2661-2.6298-1.2661z" fill="#df6277"/>
|
||||
<path d="m8.9798 1.7952-2.6298 4.5548 2.5203 1.4552 2.5208-4.3656c-0.14552-0.25205-1.2601-0.97975-2.4112-1.6443z" fill="#fb9168"/>
|
||||
<path d="m11.391 3.4396-5.041 2.9104 2.5203 1.4552 2.7389-1.4552c0-1.3292-0.07255-2.6584-0.21808-2.9104z" fill="#f3db6c"/>
|
||||
<path d="m6.35 6.35v2.9104h5.041c0.14552-0.25205 0.21807-1.5812 0.21808-2.9104z" fill="#7ab392"/>
|
||||
<path d="m6.35 6.35v2.9104l2.6298 1.6443c1.1511-0.66459 2.2657-1.3923 2.4112-1.6443z" fill="#4b7cbc"/>
|
||||
<path d="m6.35 6.35-2.5208 1.4552 2.5208 4.3656c0.29104 0 1.4787-0.60148 2.6298-1.2661z" fill="#6f488c"/>
|
||||
<path d="m3.8292 4.8948-2.5203 4.3656c0.29104 0.5041 4.459 2.9104 5.041 2.9104v-5.8208z" fill="#4d3f33"/>
|
||||
<path d="m1.309 3.4396c-0.29104 0.5041-0.29104 5.3167 0 5.8208l5.041-2.9104v-2.9104z" fill="#7a573b"/>
|
||||
<path d="m6.35 0.52917c-0.58208-2e-8 -4.75 2.4063-5.041 2.9104l5.041 2.9104z" fill="#99cd61"/>
|
||||
</g>
|
||||
<path transform="matrix(.85338 0 0 .85338 .93132 .93123)" d="m6.3498 2.9393c-0.34105 0-2.7827 1.4099-2.9532 1.7052l2.9532 5.1157 2.9538-5.1157c-0.17052-0.29535-2.6127-1.7052-2.9538-1.7052z" fill="#fff"/>
|
||||
<path transform="matrix(.88 0 0 .88 -10.906 -1.2421)" d="m16.746 6.9737 2.8639 4.9609c0.33073 0 2.6991-1.3672 2.8644-1.6536 0.16536-0.28642 0.16536-3.0209 0-3.3073l-2.8644 1.6536z" fill="#dfdfdf"/>
|
||||
<path d="m3.8299 4.8948c-0.14551 0.25205-0.14553 2.6584 0 2.9104 0.14553 0.25204 2.2292 1.4552 2.5203 1.4552v-2.9104z" fill="#d6d2d2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
BIN
apps/frontend/src/assets/logos/launchers/technic.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
apps/frontend/src/assets/logos/launchers/tlauncher.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
|
|
@ -1,8 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 514">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M503.16 323.56c11.39-42.09 12.16-87.65.04-132.8C466.57 54.2299 326.04-26.8001 189.33 9.77991 83.8101 38.0199 11.3899 128.07.689941 230.47H43.99c10.3-83.14 69.75-155.7402 155.76-178.7602 106.3-28.45 215.38 28.9601 253.42 129.6702l-42.14 11.27c-19.39-46.85-58.46-81.2-104.73-95.8302l-7.74 43.8402c36.53 13.47 66.16 43.84 77 84.25 15.8 58.89-13.62 119.23-67 144.26l11.53 42.99c70.16-28.95 112.31-101.86 102.34-177.02l41.98-11.23c4.5 28.71 2.94 57.25-3.86 84.16l42.61 15.49Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M321.99 504.22C185.27 540.8 44.7501 459.77 8.11011 323.24 3.84011 307.31 1.17 291.33 0 275.46h43.27c1.09 11.91 3.1999 23.89 6.4099 35.83 3.36 12.51 7.7701 24.46 13.1101 35.78l38.59-23.15c-3.2501-7.5-5.99-15.32-8.17-23.45-24.04-89.6 29.2-181.7 118.92-205.7099 17-4.55 34.1-6.32 50.8-5.61L255.19 133c-10.46.05-21.08 1.42-31.66 4.25-66.22 17.73-105.52 85.7-87.78 151.84 1.1 4.07 2.38 8.04 3.84 11.9l49.35-29.61-14.87-39.43 46.6-47.87 58.9-12.69 17.05 20.99-27.15 27.5-23.68 7.45-16.92 17.39 8.29 23.07s16.79 17.84 16.82 17.85l23.72-6.31 16.88-18.54 36.86-11.67 10.98 24.7-38.03 46.63-63.73 20.18-28.58-31.82-49.82 29.89c25.54 29.08 63.94 45.23 103.75 41.86l11.53 42.99c-59.41 7.86-117.44-16.73-153.49-61.91l-38.4101 23.04C136.25 451.17 223.84 484.11 309.61 461.16c61.74-16.52 109.79-58.6 135.81-111.78l42.64 15.5c-30.89 66.28-89.84 118.94-166.07 139.34Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
<svg width="64" height="64" viewBox="0 0 512 514" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M503.16 323.56C514.55 281.47 515.32 235.91 503.2 190.76C466.57 54.2299 326.04 -26.8001 189.33 9.77991C83.8101 38.0199 11.3899 128.07 0.689941 230.47H43.99C54.29 147.33 113.74 74.7298 199.75 51.7098C306.05 23.2598 415.13 80.6699 453.17 181.38L411.03 192.65C391.64 145.8 352.57 111.45 306.3 96.8198L298.56 140.66C335.09 154.13 364.72 184.5 375.56 224.91C391.36 283.8 361.94 344.14 308.56 369.17L320.09 412.16C390.25 383.21 432.4 310.3 422.43 235.14L464.41 223.91C468.91 252.62 467.35 281.16 460.55 308.07L503.16 323.56Z" fill="#00af5c"/>
|
||||
<path d="M321.99 504.22C185.27 540.8 44.7501 459.77 8.11011 323.24C3.84011 307.31 1.17 291.33 0 275.46H43.27C44.36 287.37 46.4699 299.35 49.6799 311.29C53.0399 323.8 57.45 335.75 62.79 347.07L101.38 323.92C98.1299 316.42 95.39 308.6 93.21 300.47C69.17 210.87 122.41 118.77 212.13 94.7601C229.13 90.2101 246.23 88.4401 262.93 89.1501L255.19 133C244.73 133.05 234.11 134.42 223.53 137.25C157.31 154.98 118.01 222.95 135.75 289.09C136.85 293.16 138.13 297.13 139.59 300.99L188.94 271.38L174.07 231.95L220.67 184.08L279.57 171.39L296.62 192.38L269.47 219.88L245.79 227.33L228.87 244.72L237.16 267.79C237.16 267.79 253.95 285.63 253.98 285.64L277.7 279.33L294.58 260.79L331.44 249.12L342.42 273.82L304.39 320.45L240.66 340.63L212.08 308.81L162.26 338.7C187.8 367.78 226.2 383.93 266.01 380.56L277.54 423.55C218.13 431.41 160.1 406.82 124.05 361.64L85.6399 384.68C136.25 451.17 223.84 484.11 309.61 461.16C371.35 444.64 419.4 402.56 445.42 349.38L488.06 364.88C457.17 431.16 398.22 483.82 321.99 504.22Z" fill="#00af5c"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.7 KiB |
60
apps/frontend/src/ui/components/content/LauncherIcon.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import type { ImportType } from '@onelauncher/client/bindings';
|
||||
import CurseforgeIcon from '~assets/logos/curseforge.svg?component-solid';
|
||||
import AtLauncherIcon from '~assets/logos/launchers/atlauncher.svg?component-solid';
|
||||
import FTBIcon from '~assets/logos/launchers/ftb.svg?component-solid';
|
||||
import GDLauncherImage from '~assets/logos/launchers/gdlauncher.png';
|
||||
import MultiMCImage from '~assets/logos/launchers/multimc.png';
|
||||
import PrismIcon from '~assets/logos/launchers/prismlauncher.svg?component-solid';
|
||||
import TechnicImage from '~assets/logos/launchers/technic.png';
|
||||
import TLauncherImage from '~assets/logos/launchers/tlauncher.png';
|
||||
import ModrinthIcon from '~assets/logos/modrinth.svg?component-solid';
|
||||
import UnknownImage from '~assets/logos/vanilla.png';
|
||||
import { type JSX, type JSXElement, Show, splitProps } from 'solid-js';
|
||||
|
||||
type ElementType = (props: any) => JSXElement;
|
||||
|
||||
export function getLauncherLogoElement(launcher: ImportType): ElementType {
|
||||
const providerName = launcher.toLowerCase() as Lowercase<ImportType>;
|
||||
|
||||
const image = (src: string, props: any) => <img {...props} alt={providerName} src={src} />;
|
||||
|
||||
// [provider logo, is svg]
|
||||
const mapping: Record<Lowercase<ImportType>, ElementType | string> = {
|
||||
modrinth: ModrinthIcon,
|
||||
curseforge: CurseforgeIcon,
|
||||
prismlauncher: PrismIcon,
|
||||
atlauncher: AtLauncherIcon,
|
||||
gdlauncher: GDLauncherImage,
|
||||
ftblauncher: FTBIcon,
|
||||
multimc: MultiMCImage,
|
||||
tlauncher: TLauncherImage,
|
||||
technic: TechnicImage,
|
||||
unknown: UnknownImage,
|
||||
};
|
||||
|
||||
const logo = mapping[providerName] || UnknownImage;
|
||||
if (typeof logo === 'function')
|
||||
return logo;
|
||||
|
||||
return props => image(logo, props);
|
||||
}
|
||||
|
||||
type LauncherIconProps = JSX.HTMLAttributes<HTMLImageElement> & {
|
||||
launcher: ImportType | undefined;
|
||||
};
|
||||
|
||||
function LauncherIcon(props: LauncherIconProps) {
|
||||
const [split, rest] = splitProps(props, ['launcher', 'class']);
|
||||
|
||||
return (
|
||||
<Show
|
||||
children={getLauncherLogoElement(split.launcher!)({ ...rest, ...(split.class ? { class: split.class } : {}) })}
|
||||
fallback={(
|
||||
<div class={`bg-gray-05 ${split.class || ''}`} {...rest as JSX.HTMLAttributes<HTMLDivElement>} />
|
||||
)}
|
||||
when={split.launcher !== undefined}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default LauncherIcon;
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import type { ManagedPackage, Providers } from '@onelauncher/client/bindings';
|
||||
import CurseforgeIcon from '~assets/logos/curseforge.svg?component-solid';
|
||||
import ModrinthImage from '~assets/logos/modrinth.svg?component-solid';
|
||||
import { type Component, type JSX, Match, Show, splitProps, Switch } from 'solid-js';
|
||||
|
||||
|
|
@ -8,6 +9,7 @@ export function getProviderLogoElement(provider: ManagedPackage | Providers): st
|
|||
// [provider logo, is svg]
|
||||
const mapping: Record<Lowercase<Providers>, string | Component> = {
|
||||
modrinth: ModrinthImage,
|
||||
curseforge: CurseforgeIcon,
|
||||
};
|
||||
|
||||
return mapping[providerName];
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export const enum OnboardingTaskStage {
|
|||
|
||||
interface OnboardingContextType {
|
||||
setLanguage: (language: Language) => void;
|
||||
setImportTypes: (types: ImportType[]) => void;
|
||||
setImportTypeInstances: (type: ImportType, instances: string[]) => void;
|
||||
|
||||
getTasks: () => string[];
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ function Onboarding(props: ParentProps) {
|
|||
const [forwardButtonEnabled, setForwardButtonEnabled] = createSignal(true);
|
||||
|
||||
const [language, setLanguage] = createSignal<Language>('en');
|
||||
const [importTypes, setImportTypes] = createSignal<ImportType[]>([]);
|
||||
const [importTypes, setImportTypes] = createSignal<Map<ImportType, string[]>>(new Map());
|
||||
const [tasksStage, setTasksStage] = createSignal<OnboardingTaskStage>(OnboardingTaskStage.NotStarted);
|
||||
const [tasksMessage, setTasksMessage] = createSignal<string>('');
|
||||
|
||||
|
|
@ -140,7 +140,13 @@ function Onboarding(props: ParentProps) {
|
|||
|
||||
const ctx: OnboardingContextType = {
|
||||
setLanguage,
|
||||
setImportTypes,
|
||||
setImportTypeInstances(type, instances) {
|
||||
setImportTypes((importTypes) => {
|
||||
const newMap = new Map(importTypes);
|
||||
newMap.set(type, instances);
|
||||
return newMap;
|
||||
});
|
||||
},
|
||||
|
||||
getTasks,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,24 @@
|
|||
import { useBeforeLeave } from '@solidjs/router';
|
||||
import type { ImportType } from '@onelauncher/client/bindings';
|
||||
import Illustration from '~assets/illustrations/onboarding/import_from_others.svg?component-solid';
|
||||
import Image from '~assets/logos/vanilla.png';
|
||||
import LauncherIcon from '~ui/components/content/LauncherIcon';
|
||||
import { LAUNCHER_IMPORT_TYPES } from '~utils';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-solid';
|
||||
import { For } from 'solid-js';
|
||||
import Onboarding, { OnboardingStep } from './Onboarding';
|
||||
import { createModal } from '~ui/components/overlay/Modal';
|
||||
|
||||
function OnboardingImport() {
|
||||
const ctx = Onboarding.useContext();
|
||||
|
||||
useBeforeLeave(() => {
|
||||
ctx.setImportTypes([]);
|
||||
const modal = createModal((props) => {
|
||||
|
||||
});
|
||||
|
||||
function displayImport(type: ImportType) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<OnboardingStep
|
||||
illustration={<Illustration />}
|
||||
|
|
@ -24,10 +30,10 @@ function OnboardingImport() {
|
|||
<div class="grid grid-cols-3">
|
||||
<For each={LAUNCHER_IMPORT_TYPES}>
|
||||
{type => (
|
||||
<div class="flex flex-col items-center justify-center gap-y-4 rounded-md p-4 active:bg-gray-10 hover:bg-gray-05">
|
||||
<img alt={type} class="h-16" src={Image} />
|
||||
<button class="flex flex-col items-center justify-center gap-y-4 rounded-md p-4 active:bg-gray-10 hover:bg-gray-05" onClick={() => displayImport(type)}>
|
||||
<LauncherIcon class="h-16 max-w-22 min-w-16" launcher={type} />
|
||||
<span class="text-lg font-medium">{type}</span>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
|
|
@ -38,3 +44,7 @@ function OnboardingImport() {
|
|||
}
|
||||
|
||||
export default OnboardingImport;
|
||||
|
||||
function InstancesPickerModal() {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function OnboardingSummary() {
|
|||
<AnimatedRoutes>
|
||||
<Switch>
|
||||
<Match when={ctx.tasksStage() === OnboardingTaskStage.NotStarted}>
|
||||
<div class="my-8 max-h-36 w-full flex flex-1 flex-col gap-y-2 rounded-lg bg-page-elevated p-4">
|
||||
<div class="my-8 max-h-36 w-full flex flex-1 flex-col gap-y-2 rounded-lg bg-page-elevated p-4 font-mono">
|
||||
<For each={ctx.getTasks()}>
|
||||
{task => (
|
||||
<span class="text-lg text-fg-primary">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { CodeBrowserIcon, GitMergeIcon, LinkExternal01Icon, RefreshCcw05Icon } from '@untitled-theme/icons-solid';
|
||||
import { useNavigate } from '@solidjs/router';
|
||||
import { CodeBrowserIcon, EyeIcon, GitMergeIcon, LinkExternal01Icon, RefreshCcw05Icon } from '@untitled-theme/icons-solid';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import Toggle from '~ui/components/base/Toggle';
|
||||
import ScrollableContainer from '~ui/components/ScrollableContainer';
|
||||
|
|
@ -7,7 +8,13 @@ import Sidebar from '~ui/components/Sidebar';
|
|||
import useSettings from '~ui/hooks/useSettings';
|
||||
|
||||
function SettingsDeveloper() {
|
||||
const { settings } = useSettings();
|
||||
const { settings, saveOnLeave } = useSettings();
|
||||
const navigate = useNavigate();
|
||||
|
||||
saveOnLeave(() => ({
|
||||
debug_mode: settings().debug_mode!,
|
||||
onboarding_completed: settings().onboarding_completed!,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Sidebar.Page>
|
||||
|
|
@ -44,7 +51,22 @@ function SettingsDeveloper() {
|
|||
<Button
|
||||
children="Reload"
|
||||
iconLeft={<RefreshCcw05Icon />}
|
||||
onClick={() => location.href = '/'}
|
||||
onClick={() => location.reload()}
|
||||
/>
|
||||
</SettingsRow>
|
||||
|
||||
<SettingsRow
|
||||
description="Enter onboarding mode"
|
||||
icon={<EyeIcon />}
|
||||
title="Onboarding"
|
||||
>
|
||||
<Button
|
||||
children="Open"
|
||||
iconLeft={<EyeIcon />}
|
||||
onClick={() => {
|
||||
settings().onboarding_completed = false;
|
||||
navigate('/onboarding');
|
||||
}}
|
||||
/>
|
||||
</SettingsRow>
|
||||
|
||||
|
|
|
|||
14
packages/client/src/bindings.ts
generated
|
|
@ -324,9 +324,19 @@ export const commands = {
|
|||
else return { status: 'error', error: e as any };
|
||||
}
|
||||
},
|
||||
async importLauncherInstances(launcher: ImportType, path: string | null): Promise<Result<null, string>> {
|
||||
async getLauncherInstances(launcher: ImportType, path: string | null): Promise<Result<[string, string[]], string>> {
|
||||
try {
|
||||
return { status: 'ok', data: await TAURI_INVOKE('import_launcher_instances', { launcher, path }) };
|
||||
return { status: 'ok', data: await TAURI_INVOKE('get_launcher_instances', { launcher, path }) };
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error)
|
||||
throw e;
|
||||
else return { status: 'error', error: e as any };
|
||||
}
|
||||
},
|
||||
async importInstances(launcher: ImportType, basePath: string, instances: string[]): Promise<Result<null, string>> {
|
||||
try {
|
||||
return { status: 'ok', data: await TAURI_INVOKE('import_instances', { launcher, basePath, instances }) };
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error)
|
||||
|
|
|
|||
|
|
@ -92,8 +92,14 @@ impl ImportType {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn import_instances(import: ImportType, path: PathBuf) -> crate::Result<Vec<String>> {
|
||||
let instances_dir = import.get_instances_subpath(&path).await?;
|
||||
pub async fn get_launcher_instances(import: ImportType, path: Option<PathBuf>) -> crate::Result<(PathBuf, Vec<String>)> {
|
||||
let instances_dir = import.get_instances_subpath(
|
||||
&path.unwrap_or(
|
||||
default_launcher_path(import)
|
||||
.ok_or(anyhow::anyhow!("could not get launcher base path for {import}")
|
||||
)?
|
||||
)).await?;
|
||||
|
||||
let mut instances = Vec::new();
|
||||
let mut dir = io::read_dir(&instances_dir)
|
||||
.await
|
||||
|
|
@ -113,7 +119,21 @@ pub async fn import_instances(import: ImportType, path: PathBuf) -> crate::Resul
|
|||
}
|
||||
}
|
||||
|
||||
Ok(instances)
|
||||
Ok((instances_dir, instances))
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn import_instances(
|
||||
import: ImportType,
|
||||
base_path: PathBuf,
|
||||
instances: Vec<String>,
|
||||
) -> crate::Result<()> {
|
||||
for instance in instances {
|
||||
let cluster_path = ClusterPath::new(&instance);
|
||||
import_instance(cluster_path, import, base_path.clone(), instance).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
|
|
|
|||