mirror of
https://github.com/soconnor0919/beenvoice.git
synced 2026-02-05 00:06:36 -05:00
Add user-controlled animation preferences and reduce motion support
- Persist prefersReducedMotion and animationSpeedMultiplier in user profile - Provide UI controls to toggle reduce motion and adjust animation speed globally - Centralize animation preferences via provider and useAnimationPreferences hook - Apply preferences to charts’ animations (duration, enabled/disabled) - Inline script in layout to apply preferences early and avoid FOUC - Update CSS to respect user preference with reduced motion overrides and variable animation speeds
This commit is contained in:
@@ -91,6 +91,50 @@ export const settingsRouter = createTRPCRouter({
|
||||
return user;
|
||||
}),
|
||||
|
||||
// Get animation preferences
|
||||
getAnimationPreferences: protectedProcedure.query(async ({ ctx }) => {
|
||||
const user = await ctx.db.query.users.findFirst({
|
||||
where: eq(users.id, ctx.session.user.id),
|
||||
columns: {
|
||||
prefersReducedMotion: true,
|
||||
animationSpeedMultiplier: true,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
prefersReducedMotion: user?.prefersReducedMotion ?? false,
|
||||
animationSpeedMultiplier: user?.animationSpeedMultiplier ?? 1,
|
||||
};
|
||||
}),
|
||||
|
||||
// Update animation preferences
|
||||
updateAnimationPreferences: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
prefersReducedMotion: z.boolean().optional(),
|
||||
animationSpeedMultiplier: z
|
||||
.number()
|
||||
.min(0.25, "Minimum 0.25x")
|
||||
.max(4, "Maximum 4x")
|
||||
.optional(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
await ctx.db
|
||||
.update(users)
|
||||
.set({
|
||||
...(input.prefersReducedMotion !== undefined && {
|
||||
prefersReducedMotion: input.prefersReducedMotion,
|
||||
}),
|
||||
...(input.animationSpeedMultiplier !== undefined && {
|
||||
animationSpeedMultiplier: input.animationSpeedMultiplier,
|
||||
}),
|
||||
})
|
||||
.where(eq(users.id, ctx.session.user.id));
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
// Update user profile
|
||||
updateProfile: protectedProcedure
|
||||
.input(
|
||||
|
||||
@@ -24,6 +24,9 @@ export const users = createTable("user", (d) => ({
|
||||
image: d.varchar({ length: 255 }),
|
||||
resetToken: d.varchar({ length: 255 }),
|
||||
resetTokenExpiry: d.timestamp(),
|
||||
// User UI/animation preferences
|
||||
prefersReducedMotion: d.boolean().default(false).notNull(),
|
||||
animationSpeedMultiplier: d.real().default(1).notNull(),
|
||||
}));
|
||||
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
|
||||
Reference in New Issue
Block a user