WIP model

This commit is contained in:
Eric Bailey
2024-10-08 13:24:04 -05:00
parent 95ee2a9e2c
commit f43d2ebefa
7 changed files with 81 additions and 19 deletions
+1
View File
@@ -143,6 +143,7 @@
"expo-updates": "~0.25.14",
"expo-web-browser": "~13.0.3",
"fast-text-encoding": "^1.0.6",
"fuse.js": "^7.0.0",
"history": "^5.3.0",
"hls.js": "^1.5.11",
"js-sha256": "^0.9.0",
+8 -1
View File
@@ -1,7 +1,7 @@
import {MMKV} from 'react-native-mmkv'
import {IS_DEV} from '#/env'
import {Device} from '#/storage/schema'
import {Account} from '#/storage/schema'
export * from '#/storage/schema'
@@ -74,6 +74,13 @@ export class Storage<Scopes extends unknown[], Schema> {
*/
export const device = new Storage<[], Device>({id: 'bsky_device'})
/**
* Account data that's specific to the account
*
* `account.set([did, key], true)`
*/
export const account = new Storage<[string], Account>({id: 'bsky_account'})
if (IS_DEV && typeof window !== 'undefined') {
// @ts-ignore
window.bsky_storage = {
+9
View File
@@ -1,3 +1,5 @@
import {Result} from '#/view/com/composer/text-input/tagsAutocompleteState'
/**
* Device data that's specific to the device and does not vary based account
*/
@@ -9,3 +11,10 @@ export type Device = {
countryCode: string | undefined
}
}
/**
* Account data that's specific to the current account
*/
export type Account = {
recentTags: Result[] | undefined
}
@@ -13,15 +13,17 @@ import {Text as TiptapText} from '@tiptap/extension-text'
import {generateJSON} from '@tiptap/html'
import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
import {usePalette} from '#/lib/hooks/usePalette'
import {blobToDataUri, isUriImage} from '#/lib/media/util'
import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
import {blobToDataUri, isUriImage} from 'lib/media/util'
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
import {useSession} from '#/state/session'
import {tagAutocompleteModel} from '#/view/com/composer/text-input/tagsAutocompleteState'
import {
LinkFacetMatch,
suggestLinkCardUri,
} from 'view/com/composer/text-input/text-input-util'
} from '#/view/com/composer/text-input/text-input-util'
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
import {atoms as a, useAlf} from '#/alf'
import {Portal} from '#/components/Portal'
import {normalizeTextStyles} from '#/components/Typography'
@@ -29,8 +31,7 @@ import {Text} from '../../util/text/Text'
import {createSuggestion} from './web/Autocomplete'
import {Emoji} from './web/EmojiPicker.web'
import {LinkDecorator} from './web/LinkDecorator'
import {TagDecorator} from './web/TagDecorator'
import {Tags, createTagsAutocomplete} from './web/Tags'
import {createTagsAutocomplete,Tags} from './web/Tags'
export interface TextInputRef {
focus: () => void
@@ -65,6 +66,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
const autocomplete = useActorAutocompleteFn()
const pal = usePalette('default')
const modeClass = useColorSchemeStyle('ProseMirror-light', 'ProseMirror-dark')
const {currentAccount} = useSession()
const [isDropping, setIsDropping] = React.useState(false)
@@ -78,6 +80,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
class: 'inline-tag',
},
suggestion: createTagsAutocomplete({
model: tagAutocompleteModel({currentDid: currentAccount?.did!}),
}),
}),
Mention.configure({
@@ -94,7 +97,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
History,
Hardbreak,
],
[autocomplete, placeholder],
[autocomplete, placeholder, currentAccount],
)
React.useEffect(() => {
@@ -0,0 +1,31 @@
import {account} from '#/storage'
export type Result = {
value: string
}
export type Model = {
search(query: string): Promise<Result[]>
save(tag: string): void
}
export function tagAutocompleteModel({
currentDid,
}: {
currentDid: string
}): Model {
let recentTags = account.get([currentDid, 'recentTags']) || []
return {
async search(query: string) {
if (!query) return [{value: query}]
return [{value: query}]
},
save(tag: string) {
recentTags = [
{value: tag},
...recentTags.filter(t => t.value !== tag),
].slice(0, 40)
},
}
}
@@ -9,28 +9,32 @@ import {
import tippy, {Instance as TippyInstance} from 'tippy.js'
// import {TagsAutocompleteModel} from 'state/models/ui/tags-autocomplete'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from 'view/com/util/text/Text'
import {usePalette} from '#/lib/hooks/usePalette'
import {
Model,
Result,
} from '#/view/com/composer/text-input/tagsAutocompleteState'
import {Text} from '#/view/com/util/text/Text'
import {parsePunctuationFromTag} from './utils'
type AutocompleteResult = string
type ListProps = SuggestionProps<AutocompleteResult> & {
// autocompleteModel: TagsAutocompleteModel
type ListProps = SuggestionProps<Result> & {
model: Model
}
type AutocompleteRef = {
onKeyDown: (props: SuggestionKeyDownProps) => boolean
}
export function createTagsAutocomplete({}: // autocompleteModel,
{
// autocompleteModel: TagsAutocompleteModel
export function createTagsAutocomplete({
model,
}: {
model: Model
}): Omit<SuggestionOptions, 'editor'> {
return {
/**
* This `query` param comes from the result of `findSuggestionMatch`
*/
async items({query}) {
return [query, 'javascript']
return await model.search(query)
},
render() {
let component: ReactRenderer<AutocompleteRef> | undefined
@@ -41,6 +45,7 @@ export function createTagsAutocomplete({}: // autocompleteModel,
component = new ReactRenderer(Autocomplete, {
props: {
...props,
model,
},
editor: props.editor,
})
@@ -113,7 +118,7 @@ const Autocomplete = forwardRef<AutocompleteRef, ListProps>(
const selectItem = React.useCallback(
(index: number) => {
const item = items[index]
if (item) commit(item)
if (item) commit(item.value)
},
[items, commit],
)
@@ -157,7 +162,8 @@ const Autocomplete = forwardRef<AutocompleteRef, ListProps>(
return (
<div className="items">
<View style={[pal.borderDark, pal.view, styles.container]}>
{items.map((tag, index) => {
{items.map(({value}, index) => {
const {tag} = parsePunctuationFromTag(value)
const isSelected = selectedIndex === index
const isFirst = index === 0
const isLast = index === items.length - 1
+5
View File
@@ -12153,6 +12153,11 @@ functions-have-names@^1.2.2, functions-have-names@^1.2.3:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
fuse.js@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2"
integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"