Skip to content

Commit

Permalink
[masterbots.ai] fix: restore desktop navigation link - browse section (
Browse files Browse the repository at this point in the history
…#303)

* fix:restore desktop navigation link - browse

* fix:formating

* feat:yellow combobox btn (JUN-REQUEST)

* glowing effect variant

* upt:removed /b navigation as original v

* feat:powerup mode + provider
  • Loading branch information
Bran18 authored Nov 12, 2024
1 parent f808b94 commit 4058ca9
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 64 deletions.
3 changes: 1 addition & 2 deletions apps/masterbots.ai/components/layout/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ export function Header() {
<SidebarToggle />
</React.Suspense>
<HeaderLink href="/" text="MB" />

{/* Navigation links - Hidden on mobile */}
<div className="hidden lg:flex lg:items-center">
<IconSeparator className="size-6 text-muted-foreground/50" />
<HeaderLink href="/c" text="Chat" />

{appConfig.devMode && (
<>
<HeaderLink href="/c/p" text="Pro" />
Expand Down
13 changes: 9 additions & 4 deletions apps/masterbots.ai/components/layout/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { SidebarProvider } from '@/lib/hooks/use-sidebar'
import { ThreadProvider } from '@/lib/hooks/use-thread'
import { SessionProvider } from 'next-auth/react'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
import { ThemeProviderProps } from 'next-themes/dist/types'
import type { ThemeProviderProps } from 'next-themes/dist/types'
import { ModelProvider } from '@/lib/hooks/use-model'
import { ThreadVisibilityProvider } from '@/lib/hooks/use-thread-visibility'
import { PowerUpProvider } from '@/lib/hooks/use-power-up'

export function Providers({ children, ...props }: ThemeProviderProps) {
return (
Expand All @@ -18,9 +19,13 @@ export function Providers({ children, ...props }: ThemeProviderProps) {
<SidebarProvider>
<TooltipProvider>
<SessionProvider>
<ThreadProvider>
<ThreadVisibilityProvider> {children}</ThreadVisibilityProvider>
</ThreadProvider>
<PowerUpProvider>
<ThreadProvider>
<ThreadVisibilityProvider>
{children}
</ThreadVisibilityProvider>
</ThreadProvider>
</PowerUpProvider>
</SessionProvider>
</TooltipProvider>
</SidebarProvider>
Expand Down
4 changes: 3 additions & 1 deletion apps/masterbots.ai/components/routes/chat/chat-combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '@/components/ui/popover'
import { useModel } from '@/lib/hooks/use-model'
import { AIModels } from '@/app/api/chat/models/models'
import { usePowerUp } from '@/lib/hooks/use-power-up'

//* Model options available in the combobox, each with label, value, and logo icon.
const models = [
Expand All @@ -43,6 +44,7 @@ export function ChatCombobox() {
const { selectedModel, changeModel } = useModel()
const [open, setOpen] = React.useState(false)
const [value, setValue] = React.useState(selectedModel as string)
const { isPowerUp } = usePowerUp()

return (
<Popover open={open} onOpenChange={setOpen}>
Expand All @@ -52,7 +54,7 @@ export function ChatCombobox() {
role="combobox"
aria-expanded={open}
className={cn(
buttonVariants({ size: 'sm', variant: 'outline' }),
buttonVariants({ size: 'sm', variant: isPowerUp ? 'powerUp' : 'outline' }),
'absolute left-0 top-4 size-8 rounded-full p-0 sm:left-4'
)}
>
Expand Down
127 changes: 71 additions & 56 deletions apps/masterbots.ai/components/routes/chat/chat-panel-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { ChatShareDialog } from '@/components/routes/chat/chat-share-dialog'
import { ButtonScrollToBottom } from '@/components/shared/button-scroll-to-bottom'
import { Button } from '@/components/ui/button'
import { IconRefresh, IconShare, IconStop } from '@/components/ui/icons'
import { Label } from '@/components/ui/label'
import { Switch } from '@/components/ui/switch'
import { usePowerUp } from '@/lib/hooks/use-power-up'
import * as React from 'react'

interface ChatPanelHeaderProps {
Expand Down Expand Up @@ -32,71 +35,83 @@ export function ChatPanelHeader({
isAtBottom
}: ChatPanelHeaderProps) {
const [shareDialogOpen, setShareDialogOpen] = React.useState(false)
const { isPowerUp, togglePowerUp } = usePowerUp()

return (
<div className="flex flex-col items-center justify-between w-full px-2 py-3.5 space-y-2 bg-background md:flex-row md:space-y-0">
{showReload && (
<div className="flex items-center px-2 space-x-2">
{isLoading || loadingState ? (
<>
{/* Displays loading state message if active */}
{loadingState && (
<div className="flex items-center justify-between gap-4">
<div className="flex items-center space-x-1 drop-shadow-lg">
<div className="rounded-full size-2 bg-primary animate-pulse" />
<div className="rounded-full size-2 bg-primary animate-pulse" />
<div className="rounded-full size-2 bg-primary animate-pulse" />
</div>
<p className="text-sm font-bold text-primary drop-shadow-lg">
{loadingState}
</p>
</div>
)}
<Button
variant="outline"
onClick={stop}
className="bg-background"
>
<IconStop className="mr-2" />
Stop generating
</Button>
</>
) : (
messages?.length >= 2 && (
<div className="flex items-center gap-4 mx-2">
<div className="flex items-center space-x-2">
<Switch
id="power-up"
checked={isPowerUp}
onCheckedChange={togglePowerUp}
/>
<Label htmlFor="power-up-mode" className="text-sm font-normal">
Power-Up
</Label>
</div>

{showReload && (
<div className="flex items-center px-2 space-x-2">
{isLoading || loadingState ? (
<>
<Button variant="outline" onClick={reload}>
<IconRefresh className="mr-2" />
Regenerate response
</Button>
{id && title && (
<>
<Button
variant="outline"
onClick={() => setShareDialogOpen(true)}
>
<IconShare className="mr-2" />
Share
</Button>
<ChatShareDialog
onCopy={() => setShareDialogOpen(false)} // Closes dialog after copying link.
chat={{
id,
title,
messages
}}
/>
</>
{loadingState && (
<div className="flex items-center justify-between gap-4">
<div className="flex items-center space-x-1 drop-shadow-lg">
<div className="rounded-full size-2 bg-primary animate-pulse" />
<div className="rounded-full size-2 bg-primary animate-pulse" />
<div className="rounded-full size-2 bg-primary animate-pulse" />
</div>
<p className="text-sm font-bold text-primary drop-shadow-lg">
{loadingState}
</p>
</div>
)}
<Button
variant="outline"
onClick={stop}
className="bg-background"
>
<IconStop className="mr-2" />
Stop generating
</Button>
</>
)
)}
</div>
)}
{/* ButtonScrollToBottom provides a button to scroll to the bottom of the chat */}
) : (
messages?.length >= 2 && (
<>
<Button variant="outline" onClick={reload}>
<IconRefresh className="mr-2" />
Regenerate response
</Button>
{id && title && (
<>
<Button
variant="outline"
onClick={() => setShareDialogOpen(true)}
>
<IconShare className="mr-2" />
Share
</Button>
<ChatShareDialog
onCopy={() => setShareDialogOpen(false)}
chat={{
id,
title,
messages
}}
/>
</>
)}
</>
)
)}
</div>
)}
</div>
<ButtonScrollToBottom
scrollToBottom={scrollToBottom}
isAtBottom={isAtBottom}
/>
</div>
)
}
}
2 changes: 2 additions & 0 deletions apps/masterbots.ai/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'

import { cn } from '@/lib/utils'
import {ChatCombobox} from '@/components/routes/chat/chat-combobox';

const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium shadow ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
Expand All @@ -21,6 +22,7 @@ const buttonVariants = cva(
link: 'text-primary underline-offset-4 shadow-none hover:underline',
icon: 'flex size-8 shrink-0 select-none items-center justify-center rounded-full border shadow cursor-pointer',
sideBarProfile: 'bg-transparent border-0 shadow-none justify-start',
powerUp:'border border-input animate-pulse-yellow bg-yellow-400 text-black transition-all duration-200 ease-in-out shadow-[0_0_20px_#f5be0b] hover:bg-yellow-500'
},
size: {
default: 'h-8 px-4 py-2',
Expand Down
2 changes: 1 addition & 1 deletion apps/masterbots.ai/components/ui/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Switch = React.forwardRef<
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(
"peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className
)}
{...props}
Expand Down
40 changes: 40 additions & 0 deletions apps/masterbots.ai/lib/hooks/use-power-up.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client'

import * as React from 'react'

interface PowerUpContextType {
isPowerUp: boolean
togglePowerUp: () => void
}

const PowerUpContext = React.createContext<PowerUpContextType | undefined>(undefined)

export function PowerUpProvider({ children }: { children: React.ReactNode }) {
const [isPowerUp, setIsPowerUp] = React.useState(false)

const togglePowerUp = React.useCallback(() => {
setIsPowerUp(prev => !prev)
}, [])

const value = React.useMemo(
() => ({
isPowerUp,
togglePowerUp
}),
[isPowerUp, togglePowerUp]
)

return (
<PowerUpContext.Provider value={value}>
{children}
</PowerUpContext.Provider>
)
}

export function usePowerUp() {
const context = React.useContext(PowerUpContext)
if (context === undefined) {
throw new Error('usePowerUp must be used within a PowerUpProvider')
}
return context
}

0 comments on commit 4058ca9

Please sign in to comment.