Skip to content

Commit d785fce

Browse files
authored
Fix missing message opts (#1099)
* fix message options showing * improve admin sub listing * use sub levels to determine tier * copy sub levels * improve model listing - include image models * fixing stripe check for finished checkout that didnt apply
1 parent 9f94eef commit d785fce

File tree

13 files changed

+268
-215
lines changed

13 files changed

+268
-215
lines changed

common/image-util.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ export function filterImageModels(
77
tier?: Pick<AppSchema.SubscriptionTier, 'imagesAccess'>
88
) {
99
if (user?.admin) return models
10-
if (!tier?.imagesAccess) return []
1110

12-
let level = Math.max(user?.sub?.level ?? 0, 0)
13-
14-
const list = models
15-
.filter((m) => (m.level ?? 0) <= level)
16-
.map((m) => ({ ...m, override: '', host: '' }))
11+
const list = models.map((m) => ({ ...m, override: '', host: '' }))
1712
return list
1813
}

common/types/presets.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export interface SubscriptionModelOption {
3737
preset: GenSettings &
3838
Pick<
3939
SubscriptionModel,
40-
'allowGuestUsage' | 'isDefaultSub' | '_id' | 'service' | 'levels' | 'subLevel'
40+
'allowGuestUsage' | 'isDefaultSub' | '_id' | 'service' | 'levels' | 'subLevel' | 'subDisabled'
4141
> & {
4242
kind: 'submodel'
4343
}

srv/api/billing/modify.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export const retrieveSubscription = handle(async ({ userId }) => {
8989

9090
const errors: string[] = []
9191

92-
if (user?.billing?.subscriptionId) {
92+
if (user?.billing?.subscriptionId || user?.stripeSessions?.length) {
9393
const result = await resyncSubscription(user).catch((err: Error) => ({ err }))
9494
if (!result) {
9595
errors.push(`Error occurred while retrieving subscription infomation`)

srv/api/billing/stripe.ts

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export async function resyncSubscription(user: AppSchema.User) {
8383

8484
if (billing.subscriptionId !== subscription.id) {
8585
billing.subscriptionId = subscription.id
86+
billing.customerId = subscription.customer as string
8687
}
8788

8889
/**

srv/db/subscriptions.ts

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export function toModelOption(sub: AppSchema.SubscriptionModel): AppSchema.Subsc
122122
topK: sub.topK,
123123
topP: sub.topP,
124124
minP: sub.minP,
125+
subDisabled: sub.subDisabled,
125126
typicalP: sub.typicalP,
126127
addBosToken: sub.addBosToken,
127128
antiBond: sub.antiBond,

web/pages/Admin/SubscriptionList.tsx

+96-57
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { A, useNavigate } from '@solidjs/router'
22
import { Copy, Plus, Trash } from 'lucide-solid'
3-
import { Component, createSignal, For, onMount, Show } from 'solid-js'
3+
import { Component, createMemo, createSignal, For, onMount, Show } from 'solid-js'
44
import Button from '../../shared/Button'
55
import { ConfirmModal } from '../../shared/Modal'
66
import PageHeader from '../../shared/PageHeader'
@@ -10,7 +10,7 @@ import { getServiceName, sortByLabel } from '/web/shared/adapter'
1010
import Divider from '/web/shared/Divider'
1111
import { Pill, SolidCard } from '/web/shared/Card'
1212
import { Page } from '/web/Layout'
13-
import { SubscriptionModelLevel } from '/common/types/presets'
13+
import { SubscriptionModel, SubscriptionModelLevel } from '/common/types/presets'
1414

1515
const SubscriptionList: Component = () => {
1616
setComponentPageTitle('Subscriptions')
@@ -31,6 +31,38 @@ const SubscriptionList: Component = () => {
3131
const cfg = userStore()
3232

3333
const [deleting, setDeleting] = createSignal<string>()
34+
const subCats = createMemo(() => {
35+
const cats = new Map<number, Array<SubscriptionModel & { label: string }>>()
36+
37+
for (const sub of state.enabled) {
38+
let level = sub.levels.reduce<number | null>(
39+
(prev, curr) => (prev === null ? curr.level : curr.level < prev ? curr.level : prev),
40+
null
41+
)
42+
43+
if (level === null) {
44+
level = sub.subLevel
45+
}
46+
47+
if (!cats.has(level)) {
48+
cats.set(level, [])
49+
}
50+
51+
const list = cats.get(level)
52+
list!.push(sub)
53+
cats.set(level, list!)
54+
}
55+
56+
const all = Array.from(cats.entries())
57+
.sort((l, r) => l[0] - r[0])
58+
.map(([level, list]) => ({
59+
name: `Tier ${level}`,
60+
list: list.sort((l, r) => l.name.localeCompare(r.name)),
61+
}))
62+
63+
all.push({ name: 'Disabled', list: state.disabled })
64+
return all
65+
})
3466

3567
const deleteSub = () => {
3668
const presetId = deleting()
@@ -122,62 +154,69 @@ const SubscriptionList: Component = () => {
122154
</Show>
123155
<Divider />
124156
<div class="flex justify-center font-bold">Models</div>
125-
<For each={state.enabled.concat(state.disabled)}>
126-
{(sub) => (
127-
<div class="flex w-full items-center gap-2">
128-
<A
129-
href={`/admin/subscriptions/${sub._id}`}
130-
class="flex h-12 w-full gap-2 rounded-xl hover:bg-[var(--bg-600)]"
131-
classList={{
132-
'bg-red-900': sub.subDisabled && !sub.isDefaultSub,
133-
'text-500': sub.subDisabled && !sub.isDefaultSub,
134-
'bg-800': !sub.subDisabled && !sub.isDefaultSub,
135-
'bg-[var(--hl-800)]': sub.isDefaultSub,
136-
}}
137-
>
138-
<div class="ml-4 flex w-full items-center">
139-
<div class="flex gap-1">
140-
<span class="mr-1 text-xs italic text-[var(--text-600)]">
141-
[Level: {sub.subLevel}] {getServiceName(sub.service)}
142-
</span>
143-
{sub.name}
144-
<Show when={sub.description}>
145-
<span class="text-500 ml-1 text-xs">{sub.description}</span>
146-
</Show>
147-
<span class="mr-1 text-xs italic text-[var(--text-600)]">
148-
{sub.isDefaultSub ? ' default' : ''}
149-
{sub.subDisabled ? ' (disabled)' : ''}
150-
</span>
151-
<Contexts
152-
levels={[
153-
{
154-
level: sub.subLevel,
155-
maxContextLength: sub.maxContextLength!,
156-
maxTokens: sub.maxTokens!,
157-
},
158-
]}
159-
/>
160-
<Contexts levels={sub.levels || []} />
157+
<For each={subCats()}>
158+
{(item) => (
159+
<>
160+
<div class="bold flex justify-start">{item.name}</div>
161+
<For each={item.list}>
162+
{(sub) => (
163+
<div class="flex w-full items-center gap-2">
164+
<A
165+
href={`/admin/subscriptions/${sub._id}`}
166+
class="flex h-12 w-full gap-2 rounded-xl hover:bg-[var(--bg-600)]"
167+
classList={{
168+
'bg-red-900': sub.subDisabled && !sub.isDefaultSub,
169+
'text-500': sub.subDisabled && !sub.isDefaultSub,
170+
'bg-800': !sub.subDisabled && !sub.isDefaultSub,
171+
'bg-[var(--hl-800)]': sub.isDefaultSub,
172+
}}
173+
>
174+
<div class="ml-4 flex w-full items-center">
175+
<div class="flex gap-1">
176+
<span class="mr-1 text-xs italic text-[var(--text-600)]">
177+
[Level: {sub.subLevel}] {getServiceName(sub.service)}
178+
</span>
179+
{sub.name}
180+
<Show when={sub.description}>
181+
<span class="text-500 ml-1 text-xs">{sub.description}</span>
182+
</Show>
183+
<span class="mr-1 text-xs italic text-[var(--text-600)]">
184+
{sub.isDefaultSub ? ' default' : ''}
185+
{sub.subDisabled ? ' (disabled)' : ''}
186+
</span>
187+
<Contexts
188+
levels={[
189+
{
190+
level: sub.subLevel,
191+
maxContextLength: sub.maxContextLength!,
192+
maxTokens: sub.maxTokens!,
193+
},
194+
]}
195+
/>
196+
<Contexts levels={sub.levels || []} />
197+
</div>
198+
</div>
199+
</A>
200+
<Button
201+
schema="clear"
202+
size="sm"
203+
onClick={() => nav(`/admin/subscriptions/new?preset=${sub._id}`)}
204+
class="icon-button"
205+
>
206+
<Copy />
207+
</Button>
208+
<Button
209+
schema="clear"
210+
size="sm"
211+
onClick={() => setDeleting(sub._id)}
212+
class="icon-button"
213+
>
214+
<Trash />
215+
</Button>
161216
</div>
162-
</div>
163-
</A>
164-
<Button
165-
schema="clear"
166-
size="sm"
167-
onClick={() => nav(`/admin/subscriptions/new?preset=${sub._id}`)}
168-
class="icon-button"
169-
>
170-
<Copy />
171-
</Button>
172-
<Button
173-
schema="clear"
174-
size="sm"
175-
onClick={() => setDeleting(sub._id)}
176-
class="icon-button"
177-
>
178-
<Trash />
179-
</Button>
180-
</div>
217+
)}
218+
</For>
219+
</>
181220
)}
182221
</For>
183222
</div>

web/pages/Admin/SubscriptionModel.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,9 @@ export const SubscriptionModel: Component = () => {
114114
...preset,
115115
_id: '',
116116
subLevel: 0,
117-
subModel: '',
118117
subApiKey: '',
119118
subDisabled: false,
120119
allowGuestUsage: false,
121-
levels: [],
122120
})
123121
return
124122
} else if (params.id === 'default') {

web/pages/Chat/components/Message.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,9 @@ const MessageOptions: Component<{
644644
})
645645

646646
const showInner = createMemo(() => {
647-
for (const opt of Object.values(logic())) {
648-
if (!opt.outer && opt.show) return true
647+
const logics = logic()
648+
for (const opt of Object.values(logics)) {
649+
if (!opt.outer.outer && opt.show) return true
649650
}
650651

651652
return false

web/pages/Profile/SubscriptionPage.tsx

+11-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { PatreonControls } from '../Settings/PatreonOauth'
99
import { getUserSubscriptionTier } from '/common/util'
1010
import { isLoggedIn } from '/web/store/api'
1111
import { useNavigate } from '@solidjs/router'
12+
import { ModelList } from '/web/shared/PresetSettings/Agnaistic'
1213

1314
export const SubscriptionPage: Component<{}> = (props) => {
1415
const settings = settingStore((s) => s.config)
@@ -29,6 +30,7 @@ export const SubscriptionPage: Component<{}> = (props) => {
2930
const [showUnsub, setUnsub] = createSignal(false)
3031
const [showUpgrade, setUpgrade] = createSignal<AppSchema.SubscriptionTier>()
3132
const [showDowngrade, setDowngrade] = createSignal<AppSchema.SubscriptionTier>()
33+
const [showModels, setShowModels] = createSignal(false)
3234

3335
const hasExpired = createMemo(() => {
3436
// We should leave this out. It's possible a user can subscribe multiple ways
@@ -106,9 +108,9 @@ export const SubscriptionPage: Component<{}> = (props) => {
106108
contexts.
107109
</p>
108110
<p>
109-
In the future you'll also have access to additional features! Such as: Image
110-
generation, image storage, and with third-party apps like Discord, Slack, and
111-
WhatsApp, and more!
111+
In the future you'll also have access to additional features! Such as: voice
112+
generation, image storage, and with integration third-party apps like Discord, Slack,
113+
and WhatsApp, and more!
112114
</p>
113115
<p>Subscribing allows me to spend more time developing and enhancing Agnaistic.</p>
114116
</SolidCard>
@@ -122,6 +124,10 @@ export const SubscriptionPage: Component<{}> = (props) => {
122124
</SolidCard>
123125
</Show>
124126

127+
<Button schema="primary" onClick={() => setShowModels(true)}>
128+
View Available Models
129+
</Button>
130+
125131
<PatreonControls />
126132

127133
<Show when={user.sub?.level! > 0}>
@@ -336,6 +342,8 @@ export const SubscriptionPage: Component<{}> = (props) => {
336342
}
337343
confirm={() => userStore.modifySubscription(showDowngrade()!._id)}
338344
/>
345+
346+
<ModelList show={showModels()} close={() => setShowModels(false)} />
339347
</>
340348
)
341349
}

web/pages/Profile/TierCard.tsx

-35
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ import { Component, Show, createMemo } from 'solid-js'
22
import { AppSchema } from '/common/types'
33
import { SolidCard } from '/web/shared/Card'
44
import { markdown } from '/web/shared/markdown'
5-
import { settingStore } from '/web/store'
6-
import { HelpModal } from '/web/shared/Modal'
7-
import { getSubscriptionModelLimits } from '/common/util'
8-
import Button from '/web/shared/Button'
95

106
type TierPreview = OmitId<AppSchema.SubscriptionTier, Dates | 'enabled' | 'priceId' | 'productId'>
117

@@ -14,22 +10,6 @@ export const TierCard: Component<{
1410
children?: any
1511
class?: string
1612
}> = (props) => {
17-
const settings = settingStore()
18-
19-
const models = createMemo(() => {
20-
return settings.config.subs
21-
.filter((s) => props.tier.level >= s.level)
22-
.sort((l, r) =>
23-
r.level > l.level ? 1 : r.level === l.level ? l.name.localeCompare(r.name) : -1
24-
)
25-
.map((m) => {
26-
const level = getSubscriptionModelLimits(m.preset, props.tier.level)
27-
const ctx = level ? `${Math.floor(level.maxContextLength / 1000)}k` : ''
28-
return `| ${m.name} | ${ctx} |`
29-
})
30-
.join('\n')
31-
})
32-
3313
const stripeCost = createMemo(() => {
3414
const prices: any[] = []
3515
if (props.tier.cost > 0) {
@@ -74,21 +54,6 @@ export const TierCard: Component<{
7454
<div class="markdown text-sm" innerHTML={markdown.makeHtml(props.tier.description)} />
7555
</div>
7656
<div>
77-
<Show when={models().length > 0}>
78-
<HelpModal
79-
title={`Models on ${props.tier.name}`}
80-
cta={
81-
<div class="flex justify-center">
82-
<Button size="sm">View Models</Button>
83-
</div>
84-
}
85-
>
86-
<div
87-
class="markdown text-sm"
88-
innerHTML={markdown.makeHtml(`| Model | Context |\n| ----- | ------- |\n${models()}`)}
89-
/>
90-
</HelpModal>
91-
</Show>
9257
<div class="text-md flex flex-col items-center font-bold">
9358
{stripeCost()}
9459
<Show when={props.tier.cost > 0 && !!props.tier.patreon?.cost}>

0 commit comments

Comments
 (0)