Skip to content

Commit

Permalink
feat #18 : add textures aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
Juknum committed Apr 7, 2024
1 parent 137b0a0 commit 4b01660
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 57 deletions.
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ model Resource {
model Texture {
id String @id @default(cuid())
name String
aliases String[]
contributions Contribution[]
filepath String
hash String @unique
Expand Down
60 changes: 25 additions & 35 deletions src/components/contribute/drafts/drafts-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,14 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
<Group gap="sm" wrap="nowrap">
<Avatar src={texture.filepath} size={40} radius="0" className="texture-background image-pixelated"/>
<div>
<Text size="sm">{sanitizeTextureName(texture.name)}</Text>
<Text size="sm">{texture.name}</Text>
{option.disabled && <Text size="xs" c="dimmed">Already selected!</Text>}
{/* TODO for #18 {!option.disabled && <Text size="xs" c="dimmed">{texture.aliases.join(', ')}</Text>} */}
{!option.disabled && <Text size="xs" c="dimmed">{texture.aliases.join(', ')}</Text>}
</div>
</Group>
);
};

/**
* @deprecated To be removed when #18 is implemented.
*/
const sanitizeTextureName = (name: string): string => {
return name.split('_')[1]?.split('.')[0];
};

const previousContribution = () => {
if (selectedTextureContributionsIndex === 0) return;
let index = selectedTextureContributionsIndex - 1;
Expand Down Expand Up @@ -134,7 +127,7 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
<Text size="sm">{contribution.filename}</Text>
</Group>
</Card>
<Image
<Image
src={contribution.file}
className="texture-background image-pixelated"
width={colWidth}
Expand All @@ -150,15 +143,14 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
<Text size="sm" c="dimmed">The targeted texture.</Text>
</Stack>
<Group wrap="nowrap">
<Button
<Button
variant="light"
color={gradient.to}
className="navbar-icon-fix"
loading={isPending}
onClick={() => {
startTransition(() => {
// TODO #18 look for aliases
const texture = textures.find((t) => sanitizeTextureName(t.name) === contribution.filename.replace('.png', ''));
const texture = textures.find((t) => t.name === contribution.filename.replace('.png', '') || t.aliases.includes(contribution.filename.replace('.png', '')));
if (texture) {
selectedTextureUpdated(texture.id);
}
Expand All @@ -167,23 +159,21 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
>
<PiMagicWandBold />
</Button>
<Select
<Select
limit={256}
// TODO for #18 label = texture name AND aliases
data={textures.map((t) => ({ value: t.id, label: sanitizeTextureName(t.name), disabled: t.id === selectedTexture?.id }))}
data={textures.map((t) => ({ value: t.id, label: `${t.name} ${t.aliases.join(' ')}`, disabled: t.id === selectedTexture?.id }))}
defaultValue={contribution.textureId}
renderOption={renderMultiSelectOption}
className="w-full"
onChange={selectedTextureUpdated}
onClear={() => setSelectedTexture(null)}
searchValue={sanitizeTextureName(selectedTexture?.name ?? '')}
placeholder="Search a texture..."
searchable
clearable
/>
</Group>
{selectedTexture &&
<Image
{selectedTexture &&
<Image
src={selectedTexture.filepath}
className="texture-background image-pixelated"
width={colWidth}
Expand All @@ -208,12 +198,12 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
>
<FaChevronLeft/>
</Button>
{selectedTextureContributions.length > 0 &&
{selectedTextureContributions.length > 0 &&
<Group w={50} align="center">
<Text w={50} style={{ textAlign: 'center' }}>{selectedTextureContributionsIndex + 1} / {selectedTextureContributions.length}</Text>
</Group>
}
{selectedTextureContributions.length === 0 &&
{selectedTextureContributions.length === 0 &&
<Group w={50} align="center">
<Text w={50} style={{ textAlign: 'center' }}>- / -</Text>
</Group>
Expand All @@ -228,9 +218,9 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
</Group>
{!selectedTexture && selectedTextureContributions.length === 0 &&
<Container className="texture-background" pt="100%" pl="calc(100% - var(--mantine-spacing-md))" pos="relative">
<Text
size="sm"
pos="absolute"
<Text
size="sm"
pos="absolute"
left="0"
right="0"
top="calc(50% - (20.3px /2))" // text height / 2
Expand All @@ -242,9 +232,9 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
}
{selectedTexture && selectedTextureContributions.length === 0 &&
<Container className="texture-background" pt="100%" pl="calc(100% - var(--mantine-spacing-md))" pos="relative">
<Text
size="sm"
pos="absolute"
<Text
size="sm"
pos="absolute"
left="0"
right="0"
top="calc(50% - (20.3px /2))" // text height / 2
Expand All @@ -255,7 +245,7 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
</Container>
}
{selectedTexture && selectedTextureContributions.length > 0 && displayedSelectedTextureContributions &&
<Image
<Image
src={displayedSelectedTextureContributions.file}
className="texture-background image-pixelated"
width={colWidth}
Expand All @@ -271,21 +261,21 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
<Title order={4}>Contribution Info</Title>
</Group>
<Group gap="md" justify="center">
<Select
label="Resolution"
<Select
label="Resolution"
data={Object.keys(Resolution)}
allowDeselect={false}
defaultValue={contribution.resolution}
onChange={(value) => setSelectedResolution(value as Resolution)}
style={windowWidth <= BREAKPOINT_MOBILE_LARGE ? { width: '100%' } : { width: 'calc((100% - var(--mantine-spacing-md)) * .2)' }}
required
/>
<CoAuthorsSelector
author={author}
<CoAuthorsSelector
author={author}
onCoAuthorsSelect={setSelectedCoAuthors}
defaultValue={selectedCoAuthors.map((c) => c.id)}
style={windowWidth <= BREAKPOINT_MOBILE_LARGE
? { width: '100%' }
style={windowWidth <= BREAKPOINT_MOBILE_LARGE
? { width: '100%' }
: { width: 'calc((100% - var(--mantine-spacing-md)) * .8)' }
}
/>
Expand All @@ -296,4 +286,4 @@ export function ContributionDraftModal({ contribution, textures, onClose }: Cont
</Group>
</Stack>
);
}
}
27 changes: 19 additions & 8 deletions src/server/actions/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ export async function remove(publicPath: `files/${string}`): Promise<void> {

/**
* Extracts mcmod.info from a jar file
*
*
* TODO: find behavior for Fabric mods
*
*
* @param jar the jar file to extract the mcmod.info from
* @returns The mcmod.info data
*/
Expand Down Expand Up @@ -96,7 +96,7 @@ function sanitizeMCModInfo(mcmodInfo: MCModInfoData): MCModInfo[] {
* Extract mod(s) versions from given JAR file
* - If mod(s) does not exist, create it
* - If mod(s) version(s) does not exist, create it and extract the default resource pack
*
*
* @param jar the jar file to extract the mod versions from
* @returns The extracted mod versions
*/
Expand Down Expand Up @@ -138,9 +138,9 @@ export async function extractModVersionsFromJAR(

/**
* Extract blocks and items models, textures to the /public dir
*
*
* TODO add support for models
*
*
* @param jar The jar file to extract the resources from
* @param modVersion The mod version to extract the resources from and to be linked to the extracted resources
*/
Expand Down Expand Up @@ -171,19 +171,30 @@ export async function extractDefaultResourcePack(jar: File, modVersion: ModVersi
const buffer = await textureAsset.buffer();
const hash = calculateHash(buffer);

const fileExtension = textureAsset.path.split('.').pop()!;
const textureName = textureAsset.path.split('/').pop()!.split('.')[0];

let texture = await findTexture({ hash });
if (!texture) {
const filename = `${uuid}_${textureAsset.path.split('/').pop()}`;
const filename = `${uuid}_${textureName}.${fileExtension}`;
const filepath = join(fileDir, filename);

writeFileSync(filepath, buffer);

texture = await createTexture({
filepath: join('files', 'textures', 'default', filename),
hash,
name: filename,
name: textureName,
});
}
else {
if (texture.name !== textureName && !texture.aliases.includes(textureName)) {
await db.texture.update({
where: { id: texture.id },
data: { aliases: { set: [...texture.aliases, textureName] } },
})
}
}

let resource = await getResource({ asset, modVersion });
if (!resource) resource = await createResource({ asset, modVersion });
Expand All @@ -196,4 +207,4 @@ function calculateHash(buffer: Buffer) {
const hash = createHash('sha256');
hash.update(buffer);
return hash.digest('hex');
}
}
24 changes: 10 additions & 14 deletions src/server/data/mods-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,24 @@ import { extractModVersionsFromJAR } from '../actions/files';
export async function getModVersionsWithModpacks(modId: string): Promise<ModVersionWithModpacks[]> {
const res: ModVersionWithModpacks[] = [];
const modVersions = await db.modVersion.findMany({ where: { modId } });

for (const modVer of modVersions) {
const modpacks = await db.modpackVersion.findMany({ where: { mods: { some: { id: modVer.id }}}, include: { modpack: true }})
.then((mvs) => mvs.map((mv) => mv.modpack));

res.push({ ...modVer, modpacks });
}

return res;
}

function randInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1) + min);
return res;
}

export async function getModsVersionsProgression(): Promise<ModVersionWithProgression[]> {
const modVersions = (await db.modVersion.findMany({ include: { mod: true, resources: true } }))
.map((modVer) => ({
...modVer,
...EMPTY_PROGRESSION,
resources: modVer.resources.map((resource) => ({
...resource,
.map((modVer) => ({
...modVer,
...EMPTY_PROGRESSION,
resources: modVer.resources.map((resource) => ({
...resource,
...EMPTY_PROGRESSION,
})),
}));
Expand All @@ -45,8 +41,8 @@ export async function getModsVersionsProgression(): Promise<ModVersionWithProgre
const linkedTextures = await db.linkedTexture.findMany({ where: { resourceId: resource.id }});

const textures = await db.texture.findMany({
where: {
id: { in: linkedTextures.map((lt) => lt.textureId) },
where: {
id: { in: linkedTextures.map((lt) => lt.textureId) },
},
});

Expand Down Expand Up @@ -101,7 +97,7 @@ export async function addModVersionsFromJAR(jar: FormData): Promise<ModVersion[]

export async function createModVersion({ mod, version, mcVersion }: { mod: { id: string }, version: string, mcVersion: string }): Promise<ModVersion> {
await canAccess();

return db.modVersion.create({ data: { modId: mod.id, version, mcVersion } });
}

Expand Down

0 comments on commit 4b01660

Please sign in to comment.