Skip to content

Commit f49dc71

Browse files
committed
feat: SkyClient Part 1
1 parent 2554d23 commit f49dc71

File tree

15 files changed

+410
-85
lines changed

15 files changed

+410
-85
lines changed
751 Bytes
Loading

apps/frontend/src/ui/components/content/ProviderIcon.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { ManagedPackage, Providers } from '@onelauncher/client/bindings';
22
import CurseforgeIcon from '~assets/logos/curseforge.svg?component-solid';
33
import ModrinthImage from '~assets/logos/modrinth.svg?component-solid';
4+
import SkyClientImage from '~assets/logos/skyclient.png';
45
import { type Component, type JSX, Match, Show, splitProps, Switch } from 'solid-js';
56

67
export function getProviderLogoElement(provider: ManagedPackage | Providers): string | Component {
@@ -10,6 +11,7 @@ export function getProviderLogoElement(provider: ManagedPackage | Providers): st
1011
const mapping: Record<Lowercase<Providers>, string | Component> = {
1112
modrinth: ModrinthImage,
1213
curseforge: CurseforgeIcon,
14+
skyclient: SkyClientImage,
1315
};
1416

1517
return mapping[providerName];

apps/frontend/src/ui/components/content/SearchResults.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,18 @@ function PackageItem(props: SearchResult & { provider: Providers; row?: boolean
160160
<p class="max-h-22 flex-1 overflow-hidden text-sm text-fg-secondary line-height-snug">{props.description}</p>
161161

162162
<div class="flex flex-row gap-4 text-xs">
163-
<div class="flex flex-row items-center gap-2">
164-
<Download01Icon class="h-4 w-4" />
165-
{abbreviateNumber(props.downloads)}
166-
</div>
167-
168-
<Show when={props.follows > 0}>
163+
<Show when={props.provider !== 'SkyClient'}>
169164
<div class="flex flex-row items-center gap-2">
170-
<HeartIcon class="h-4 w-4" />
171-
{abbreviateNumber(props.follows)}
165+
<Download01Icon class="h-4 w-4" />
166+
{abbreviateNumber(props.downloads)}
172167
</div>
168+
169+
<Show when={props.follows > 0}>
170+
<div class="flex flex-row items-center gap-2">
171+
<HeartIcon class="h-4 w-4" />
172+
{abbreviateNumber(props.follows)}
173+
</div>
174+
</Show>
173175
</Show>
174176
</div>
175177
</div>

apps/frontend/src/ui/pages/browser/BrowserPackage.tsx

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ export default BrowserPackage;
137137

138138
function BrowserSidebar(props: { package: ManagedPackage }) {
139139
const [authors] = useCommand(() => props.package, () => bridge.commands.getProviderAuthors(props.package.provider, props.package.author));
140-
const createdAt = () => new Date(props.package.created);
141-
const updatedAt = () => new Date(props.package.updated);
140+
const createdAt = createMemo(() => props.package.created ? new Date(props.package.created) : null);
141+
const updatedAt = createMemo(() => props.package.updated ? new Date(props.package.updated) : null);
142142
const promptOpen = usePromptOpener();
143143

144144
return (
@@ -166,16 +166,18 @@ function BrowserSidebar(props: { package: ManagedPackage }) {
166166
<p class="max-h-22 flex-1 overflow-hidden text-sm text-fg-secondary line-height-snug">{props.package.description}</p>
167167

168168
<div class="flex flex-row gap-4 text-xs">
169-
<div class="flex flex-row items-center gap-2">
170-
<Download01Icon class="h-4 w-4" />
171-
{abbreviateNumber(props.package.downloads)}
172-
</div>
173-
174-
<Show when={props.package.followers > 0}>
169+
<Show when={props.package.provider !== 'SkyClient'}>
175170
<div class="flex flex-row items-center gap-2">
176-
<HeartIcon class="h-4 w-4" />
177-
{abbreviateNumber(props.package.followers)}
171+
<Download01Icon class="h-4 w-4" />
172+
{abbreviateNumber(props.package.downloads)}
178173
</div>
174+
175+
<Show when={props.package.followers > 0}>
176+
<div class="flex flex-row items-center gap-2">
177+
<HeartIcon class="h-4 w-4" />
178+
{abbreviateNumber(props.package.followers)}
179+
</div>
180+
</Show>
179181
</Show>
180182
</div>
181183
</div>
@@ -235,25 +237,29 @@ function BrowserSidebar(props: { package: ManagedPackage }) {
235237
</div>
236238
</Show>
237239

238-
<Tooltip text={createdAt().toLocaleString()}>
239-
<div class="flex flex-row items-center gap-x-1">
240-
<CalendarIcon class="h-3 min-w-3 w-3" />
241-
Created
242-
<span class="text-fg-primary font-medium">
243-
{formatAsRelative(createdAt().getTime(), 'en', 'long')}
244-
</span>
245-
</div>
246-
</Tooltip>
240+
<Show when={createdAt() !== null}>
241+
<Tooltip text={createdAt()!.toLocaleString()}>
242+
<div class="flex flex-row items-center gap-x-1">
243+
<CalendarIcon class="h-3 min-w-3 w-3" />
244+
Created
245+
<span class="text-fg-primary font-medium">
246+
{formatAsRelative(createdAt()!.getTime(), 'en', 'long')}
247+
</span>
248+
</div>
249+
</Tooltip>
250+
</Show>
247251

248-
<Tooltip text={updatedAt().toLocaleString()}>
249-
<div class="flex flex-row items-center gap-x-1">
250-
<ClockRewindIcon class="h-3 min-w-3 w-3" />
251-
Last Updated
252-
<span class="text-fg-primary font-medium">
253-
{formatAsRelative(updatedAt().getTime(), 'en', 'long')}
254-
</span>
255-
</div>
256-
</Tooltip>
252+
<Show when={updatedAt() !== null}>
253+
<Tooltip text={updatedAt()!.toLocaleString()}>
254+
<div class="flex flex-row items-center gap-x-1">
255+
<ClockRewindIcon class="h-3 min-w-3 w-3" />
256+
Last Updated
257+
<span class="text-fg-primary font-medium">
258+
{formatAsRelative(updatedAt()!.getTime(), 'en', 'long')}
259+
</span>
260+
</div>
261+
</Tooltip>
262+
</Show>
257263
</div>
258264

259265
</div>

apps/frontend/src/ui/pages/browser/BrowserRoot.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ProviderIcon from '~ui/components/content/ProviderIcon';
77
import useBrowser from '~ui/hooks/useBrowser';
88
import { PROVIDERS } from '~utils';
99
import { browserCategories } from '~utils/browser';
10-
import { For, type JSX, type ParentProps } from 'solid-js';
10+
import { createMemo, For, type JSX, type ParentProps, Show } from 'solid-js';
1111
import BrowserMain from './BrowserMain';
1212
import BrowserPackage from './BrowserPackage';
1313
import BrowserSearch from './BrowserSearch';
@@ -87,23 +87,29 @@ function BrowserCategories() {
8787
browser.search();
8888
};
8989

90+
const categories = createMemo(() => {
91+
return browserCategories.byPackageType(browser.packageType(), browser.searchQuery().provider);
92+
});
93+
9094
return (
9195
<div class="top-0 grid grid-cols-[1fr_auto] h-fit min-w-50 gap-y-6">
9296
<div />
9397
<div class="flex flex-col gap-y-6">
94-
<div class="flex flex-col gap-y-2">
95-
<h6 class="my-1">Categories</h6>
96-
<For each={browserCategories.byPackageType(browser.packageType(), browser.searchQuery().provider)}>
97-
{category => (
98-
<p
99-
class={`text-md capitalize text-fg-primary hover:text-fg-primary-hover line-height-snug ${isEnabled(category.id) ? 'text-opacity-100! hover:text-opacity-90!' : 'text-opacity-60! hover:text-opacity-70!'}`}
100-
onClick={() => toggleCategory(category.id)}
101-
>
102-
{category.display}
103-
</p>
104-
)}
105-
</For>
106-
</div>
98+
<Show when={categories().length > 0}>
99+
<div class="flex flex-col gap-y-2">
100+
<h6 class="my-1">Categories</h6>
101+
<For each={categories()}>
102+
{category => (
103+
<p
104+
class={`text-md capitalize text-fg-primary hover:text-fg-primary-hover line-height-snug ${isEnabled(category.id) ? 'text-opacity-100! hover:text-opacity-90!' : 'text-opacity-60! hover:text-opacity-70!'}`}
105+
onClick={() => toggleCategory(category.id)}
106+
>
107+
{category.display}
108+
</p>
109+
)}
110+
</For>
111+
</div>
112+
</Show>
107113
</div>
108114
</div>
109115
);

apps/frontend/src/utils/browser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,5 @@ const modMapping: Record<Providers, CategoryItem[]> = {
9393
{ display: 'Utility', id: 'utility' },
9494
{ display: 'World Generation', id: 'worldgen' },
9595
],
96+
SkyClient: [],
9697
};

apps/frontend/src/utils/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,14 @@ export function getPackageUrl(pkg: ManagedPackage): string {
174174

175175
return `https://www.curseforge.com/minecraft/${packageTypeMapping[pkg.package_type]}/${pkg.main}`;
176176
},
177+
SkyClient: () => 'TODO',
177178
};
178179

179180
return mapping[pkg.provider]();
180181
}
181182

182183
export const LOADERS: Loader[] = ['vanilla', 'fabric', 'forge', 'neoforge', 'quilt'] as const;
183-
export const PROVIDERS: Providers[] = ['Modrinth', 'Curseforge'] as const;
184+
export const PROVIDERS: Providers[] = ['Modrinth', 'Curseforge', 'SkyClient'] as const;
184185
export const PACKAGE_TYPES: PackageType[] = ['mod', 'resourcepack', 'datapack', 'shaderpack'] as const;
185186
export const LAUNCHER_IMPORT_TYPES: ImportType[] = [
186187
'PrismLauncher',

packages/client/src/bindings.ts

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/src/api/package/content/curseforge.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ impl From<CurseforgePackage> for ManagedPackage {
146146
game_versions: vec![],
147147
loaders: vec![],
148148
icon_url: package.logo.and_then(|l| Some(l.url)),
149-
created: package.date_created,
150-
updated: package.date_modified,
149+
created: Some(package.date_created),
150+
updated: Some(package.date_modified),
151151
client: crate::store::PackageSide::Unknown,
152152
server: crate::store::PackageSide::Unknown,
153153
downloads: package.download_count,
@@ -193,11 +193,10 @@ impl Into<SearchResult> for CurseforgePackage {
193193
downloads: self.download_count,
194194
icon_url: self.logo.map_or(String::new(), |l| l.url),
195195
categories: vec![], // TODO
196-
display_categories: vec![],
197196
versions: vec![],
198197
follows: self.thumbs_up_count,
199-
date_created: self.date_created,
200-
date_modified: self.date_modified,
198+
date_created: Some(self.date_created),
199+
date_modified: Some(self.date_modified),
201200
}
202201
}
203202
}

packages/core/src/api/package/content/mod.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ use crate::{Result, State};
1717

1818
mod curseforge;
1919
mod modrinth;
20+
mod skyclient;
2021

2122
/// Providers for content packages
2223
#[cfg_attr(feature = "specta", derive(specta::Type))]
2324
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
2425
pub enum Providers {
2526
Modrinth,
2627
Curseforge,
28+
SkyClient,
2729
}
2830

2931
impl std::fmt::Display for Providers {
@@ -39,6 +41,7 @@ impl Providers {
3941
match self {
4042
Self::Modrinth => "Modrinth",
4143
Self::Curseforge => "Curseforge",
44+
Self::SkyClient => "SkyClient",
4245
}
4346
}
4447

@@ -48,11 +51,12 @@ impl Providers {
4851
match self {
4952
Self::Modrinth => "https://modrinth.com",
5053
Self::Curseforge => "https://curseforge.com",
54+
Self::SkyClient => "https://skyclient.co",
5155
}
5256
}
5357

5458
pub const fn get_providers() -> &'static [Providers] {
55-
&[Self::Modrinth, Self::Curseforge]
59+
&[Self::Modrinth, Self::Curseforge, Self::SkyClient]
5660
}
5761

5862
#[allow(clippy::too_many_arguments)]
@@ -98,35 +102,37 @@ impl Providers {
98102
)
99103
.await
100104
}
105+
Self::SkyClient => {
106+
skyclient::search(
107+
query,
108+
limit,
109+
offset,
110+
game_versions,
111+
loaders
112+
).await
113+
},
101114
}
102115
}
103116

104117
pub async fn get(&self, slug_or_id: &str) -> Result<ManagedPackage> {
105118
Ok(match self {
106119
Self::Modrinth => modrinth::get(slug_or_id).await?.into(),
107-
Self::Curseforge => curseforge::get(
108-
slug_or_id
109-
.parse::<u32>()
110-
.map_err(|err| anyhow::anyhow!(err))?,
111-
)
112-
.await?
113-
.into(),
120+
Self::Curseforge => curseforge::get(slug_or_id.parse::<u32>().map_err(|err| anyhow::anyhow!(err))?).await?.into(),
121+
Self::SkyClient => skyclient::get(slug_or_id).await?.into(),
114122
})
115123
}
116124

117125
pub async fn get_multiple(&self, slug_or_ids: &[String]) -> Result<Vec<ManagedPackage>> {
118-
Ok(match self {
119-
Self::Modrinth => {
120-
if slug_or_ids.len() <= 0 {
121-
return Ok(vec![]);
122-
}
126+
if slug_or_ids.len() <= 0 {
127+
return Ok(vec![]);
128+
}
123129

124-
modrinth::get_multiple(slug_or_ids)
130+
Ok(match self {
131+
Self::Modrinth => modrinth::get_multiple(slug_or_ids)
125132
.await?
126133
.into_iter()
127134
.map(Into::into)
128-
.collect()
129-
},
135+
.collect(),
130136
Self::Curseforge => {
131137
let parsed_ids = slug_or_ids
132138
.iter()
@@ -145,6 +151,11 @@ impl Providers {
145151
.map(Into::into)
146152
.collect()
147153
},
154+
Self::SkyClient => skyclient::get_multiple(slug_or_ids)
155+
.await?
156+
.into_iter()
157+
.map(Into::into)
158+
.collect(),
148159
})
149160
}
150161

@@ -166,6 +177,8 @@ impl Providers {
166177
let data = curseforge::get_all_versions(project_id, game_versions, loaders, page, page_size).await?;
167178
(data.0.into_iter().map(Into::into).collect(), data.1)
168179
}
180+
181+
Self::SkyClient => todo!(),
169182
})
170183
}
171184

@@ -181,6 +194,7 @@ impl Providers {
181194
.into_iter()
182195
.map(Into::into)
183196
.collect(),
197+
Self::SkyClient => todo!(),
184198
})
185199
}
186200

@@ -215,7 +229,8 @@ impl Providers {
215229
.await?
216230
.into_iter()
217231
.map(|(hash, version)| (hash, version.into()))
218-
.collect()
232+
.collect(),
233+
Self::SkyClient => todo!(),
219234
})
220235
}
221236
}

0 commit comments

Comments
 (0)