feat: add multiple way to show collections and links

This commit is contained in:
Sonny
2025-08-21 02:27:51 +02:00
parent 18fe979069
commit 4ef2b639b6
41 changed files with 785 additions and 164 deletions

View File

@@ -0,0 +1,26 @@
import { getDisplayPreferences } from '#shared/lib/display_preferences';
import { updateDisplayPreferencesValidator } from '#user/validators/update_display_preferences';
import { HttpContext } from '@adonisjs/core/http';
export default class DisplayPreferencesController {
async update({ request, response, auth }: HttpContext) {
const { displayPreferences } = await request.validateUsing(
updateDisplayPreferencesValidator
);
const userPrefs = auth.user!.displayPreferences ?? {};
const mergedPrefs = {
linkListDisplay:
displayPreferences.linkListDisplay ??
userPrefs.linkListDisplay ??
getDisplayPreferences().linkListDisplay,
collectionListDisplay:
displayPreferences.collectionListDisplay ??
userPrefs.collectionListDisplay ??
getDisplayPreferences().collectionListDisplay,
};
auth.user!.displayPreferences = mergedPrefs;
console.log(auth.user!.displayPreferences);
await auth.user!.save();
return response.redirect().withQs().back();
}
}

12
app/user/lib/index.ts Normal file
View File

@@ -0,0 +1,12 @@
import { type DisplayPreferences } from '#shared/types/index';
import User from '#user/models/user';
export function ensureDisplayPreferences(user: User): DisplayPreferences {
const defaults: DisplayPreferences = {
linkListDisplay: 'grid',
collectionListDisplay: 'list',
};
user.displayPreferences = { ...defaults, ...user.displayPreferences };
return user.displayPreferences;
}

View File

@@ -1,6 +1,8 @@
import Collection from '#collections/models/collection';
import AppBaseModel from '#core/models/app_base_model';
import Link from '#links/models/link';
import { type DisplayPreferences } from '#shared/types/index';
import { ensureDisplayPreferences } from '#user/lib/index';
import type { GoogleToken } from '@adonisjs/ally/types';
import { column, computed, hasMany } from '@adonisjs/lucid/orm';
import type { HasMany } from '@adonisjs/lucid/types/relations';
@@ -51,4 +53,15 @@ export default class User extends AppBaseModel {
autoUpdate: true,
})
declare lastSeenAt: DateTime;
@column({
serialize: (value) => {
if (typeof value === 'string') {
return ensureDisplayPreferences(JSON.parse(value));
}
return value;
},
prepare: (value) => JSON.stringify(value),
})
declare displayPreferences: DisplayPreferences;
}

View File

@@ -1 +1,2 @@
import './user_display_preferences_route.js';
import './user_theme_route.js';

View File

@@ -0,0 +1,10 @@
import { middleware } from '#start/kernel';
import router from '@adonisjs/core/services/router';
const DisplayPreferencesController = () =>
import('#user/controllers/display_preferences_controller');
router
.post('/user/display-preferences', [DisplayPreferencesController, 'update'])
.as('user.update-display-preferences')
.middleware([middleware.auth()]);

View File

@@ -0,0 +1,26 @@
import {
COLLECTION_LIST_DISPLAYS,
DEFAULT_LIST_DISPLAY_PREFERENCES,
LINK_LIST_DISPLAYS,
} from '#shared/lib/display_preferences';
import vine from '@vinejs/vine';
export const updateDisplayPreferencesValidator = vine.compile(
vine.object({
displayPreferences: vine.object({
linkListDisplay: vine
.enum(LINK_LIST_DISPLAYS)
.optional()
.transform(
(value) => value ?? DEFAULT_LIST_DISPLAY_PREFERENCES.linkListDisplay
),
collectionListDisplay: vine
.enum(COLLECTION_LIST_DISPLAYS)
.optional()
.transform(
(value) =>
value ?? DEFAULT_LIST_DISPLAY_PREFERENCES.collectionListDisplay
),
}),
})
);