feat: Integrate official drive_provider, update user profile features & UI improvements
All checks were successful
CI / container-job (push) Successful in 41s
All checks were successful
CI / container-job (push) Successful in 41s
- adonisrc.ts: Load official drive_provider and unload custom driver_provider. - packages.json: Add @headlessui/vue dependency for tab components. - AvatarController.ts: Rewrite avatar generation logic to always return the same avatar per user. - auth/UserController.ts: Add profile and profileUpdate methods to support user profile editing. - Submitter/datasetController.ts & app/models/file.ts: Adapt code to use the official drive_provider. - app/models/user.ts: Introduce “isAdmin” getter. - config/drive.ts: Create new configuration for the official drive_provider. - providers/vinejs_provider.ts: Adapt allowedExtensions control to use provided options or database enabled extensions. - resource/js/app.ts: Load default Head and Link components. - resources/js/menu.ts: Add settings-profile.edit menu point. - resources/js/Components/action-message.vue: Add new component for improved user feedback after form submissions. - New avatar-input.vue component: Enable profile picture selection. - Components/CardBox.vue: Alter layout to optionally show HeaderIcon in title bar. - FormControl.vue: Define a readonly prop for textareas. - Improve overall UI with updates to NavBar.vue, UserAvatar.vue, UserAvatarCurrentUser.vue, and add v-model support to password-meter.vue. - Remove profile editing logic from AccountInfo.vue and introduce new profile components (show.vue, update-password-form.vue, update-profile-information.vue). - app.edge: Modify page (add @inertiaHead tag) for better meta management. - routes.ts: Add new routes for editing user profiles. - General npm updates.
This commit is contained in:
parent
a41b091214
commit
36cd7a757b
34 changed files with 1396 additions and 407 deletions
|
@ -1,34 +1,28 @@
|
|||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
// import * as fs from 'fs';
|
||||
// import * as path from 'path';
|
||||
|
||||
const prefixes = ['von', 'van'];
|
||||
|
||||
// node ace make:controller Author
|
||||
export default class AvatarController {
|
||||
public async generateAvatar({ request, response }: HttpContext) {
|
||||
try {
|
||||
const { name, background, textColor, size } = request.only(['name', 'background', 'textColor', 'size']);
|
||||
const { name, size } = request.only(['name', 'size']);
|
||||
|
||||
// Generate initials
|
||||
// const initials = name
|
||||
// .split(' ')
|
||||
// .map((part) => part.charAt(0).toUpperCase())
|
||||
// .join('');
|
||||
const initials = this.getInitials(name);
|
||||
|
||||
// Define SVG content with dynamic values for initials, background color, text color, and size
|
||||
const originalColor = this.getColorFromName(name);
|
||||
const backgroundColor = this.lightenColor(originalColor, 60);
|
||||
const textColor = this.darkenColor(originalColor);
|
||||
|
||||
const svgContent = `
|
||||
<svg width="${size || 50}" height="${size || 50}" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="#${background || '7F9CF5'}"/>
|
||||
<rect width="100%" height="100%" fill="#${backgroundColor}"/>
|
||||
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-weight="bold" font-family="Arial, sans-serif" font-size="${
|
||||
(size / 100) * 40 || 25
|
||||
}" fill="#${textColor || 'ffffff'}">${initials}</text>
|
||||
}" fill="#${textColor}">${initials}</text>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
// Set response headers for SVG content
|
||||
response.header('Content-type', 'image/svg+xml');
|
||||
response.header('Cache-Control', 'no-cache');
|
||||
response.header('Pragma', 'no-cache');
|
||||
|
@ -62,4 +56,49 @@ export default class AvatarController {
|
|||
|
||||
return initials;
|
||||
}
|
||||
|
||||
private getColorFromName(name: string) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < name.length; i++) {
|
||||
hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
let color = '#';
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const value = (hash >> (i * 8)) & 0xff;
|
||||
color += ('00' + value.toString(16)).substr(-2);
|
||||
}
|
||||
return color.replace('#', '');
|
||||
}
|
||||
|
||||
private lightenColor(hexColor: string, percent: number) {
|
||||
let r = parseInt(hexColor.substring(0, 2), 16);
|
||||
let g = parseInt(hexColor.substring(2, 4), 16);
|
||||
let b = parseInt(hexColor.substring(4, 6), 16);
|
||||
|
||||
r = Math.floor((r * (100 + percent)) / 100);
|
||||
g = Math.floor((g * (100 + percent)) / 100);
|
||||
b = Math.floor((b * (100 + percent)) / 100);
|
||||
|
||||
r = r < 255 ? r : 255;
|
||||
g = g < 255 ? g : 255;
|
||||
b = b < 255 ? b : 255;
|
||||
|
||||
const lighterHex = ((r << 16) | (g << 8) | b).toString(16);
|
||||
|
||||
return lighterHex.padStart(6, '0');
|
||||
}
|
||||
|
||||
private darkenColor(hexColor: string) {
|
||||
const r = parseInt(hexColor.slice(0, 2), 16);
|
||||
const g = parseInt(hexColor.slice(2, 4), 16);
|
||||
const b = parseInt(hexColor.slice(4, 6), 16);
|
||||
|
||||
const darkerR = Math.round(r * 0.6);
|
||||
const darkerG = Math.round(g * 0.6);
|
||||
const darkerB = Math.round(b * 0.6);
|
||||
|
||||
const darkerColor = ((darkerR << 16) + (darkerG << 8) + darkerB).toString(16);
|
||||
|
||||
return darkerColor.padStart(6, '0');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue