feat: 项目初始化、完成基本流式传输和语音识别功能
This commit is contained in:
9
web/src/utils/context.ts
Normal file
9
web/src/utils/context.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { LoadingBarApiInjection } from "naive-ui/es/loading-bar/src/LoadingBarProvider"
|
||||
import type { MessageApiInjection } from "naive-ui/es/message/src/MessageProvider"
|
||||
import type { NotificationApiInjection } from "naive-ui/es/notification/src/NotificationProvider"
|
||||
|
||||
export const context: {
|
||||
message?: MessageApiInjection
|
||||
notification?: NotificationApiInjection
|
||||
loadingBar?: LoadingBarApiInjection
|
||||
} = {}
|
||||
6
web/src/utils/index.ts
Normal file
6
web/src/utils/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from "./context"
|
||||
export * from "./media"
|
||||
export * from "./pcm"
|
||||
export * from "./title"
|
||||
export * from "./title"
|
||||
export * from "./url"
|
||||
43
web/src/utils/media.ts
Normal file
43
web/src/utils/media.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/** 视窗匹配回调函数 */
|
||||
export const matchMedia = (
|
||||
type: "sm" | "md" | "lg" | string,
|
||||
matchFunc?: Function,
|
||||
mismatchFunc?: Function,
|
||||
) => {
|
||||
if (type === "sm") {
|
||||
if (window.matchMedia("(max-width: 767.98px)").matches) {
|
||||
/* 窗口小于或等于 */
|
||||
matchFunc?.()
|
||||
}
|
||||
else {
|
||||
mismatchFunc?.()
|
||||
}
|
||||
}
|
||||
else if (type === "md") {
|
||||
if (window.matchMedia("(max-width: 992px)").matches) {
|
||||
/* 窗口小于或等于 */
|
||||
matchFunc?.()
|
||||
}
|
||||
else {
|
||||
mismatchFunc?.()
|
||||
}
|
||||
}
|
||||
else if (type === "lg") {
|
||||
if (window.matchMedia("(max-width: 1200px)").matches) {
|
||||
/* 窗口小于或等于 */
|
||||
matchFunc?.()
|
||||
}
|
||||
else {
|
||||
mismatchFunc?.()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (window.matchMedia(`(max-width: ${type}px)`).matches) {
|
||||
/* 窗口小于或等于 */
|
||||
matchFunc?.()
|
||||
}
|
||||
else {
|
||||
mismatchFunc?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
12
web/src/utils/pcm.ts
Normal file
12
web/src/utils/pcm.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export const convertToPCM16 = (float32Array: Float32Array): Uint8Array => {
|
||||
const int16Buffer = new Int16Array(float32Array.length)
|
||||
for (let i = 0; i < float32Array.length; i++) {
|
||||
int16Buffer[i] = Math.max(-1, Math.min(1, float32Array[i])) * 0x7FFF
|
||||
}
|
||||
const buffer = new ArrayBuffer(int16Buffer.length * 2)
|
||||
const view = new DataView(buffer)
|
||||
for (let i = 0; i < int16Buffer.length; i++) {
|
||||
view.setInt16(i * 2, int16Buffer[i], true)
|
||||
}
|
||||
return new Uint8Array(buffer)
|
||||
}
|
||||
25
web/src/utils/title.ts
Normal file
25
web/src/utils/title.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useTitle } from "@vueuse/core"
|
||||
|
||||
const DEFAULT_TITLE = "Agent"
|
||||
|
||||
const DEFAULT_DESCRIPTION = document
|
||||
.querySelector("meta[name='description']")
|
||||
?.getAttribute("content")
|
||||
|
||||
export function setTitle(title?: string) {
|
||||
useTitle().value = (title ? `${title} | ` : "") + DEFAULT_TITLE
|
||||
}
|
||||
|
||||
export function resetDescription() {
|
||||
document
|
||||
.querySelector("meta[name='description']")
|
||||
?.setAttribute("content", DEFAULT_DESCRIPTION!)
|
||||
}
|
||||
|
||||
export function setDescription(description?: string) {
|
||||
if (!description)
|
||||
return
|
||||
document
|
||||
.querySelector("meta[name='description']")
|
||||
?.setAttribute("content", `${description} | ${DEFAULT_TITLE}`)
|
||||
}
|
||||
15
web/src/utils/url.ts
Normal file
15
web/src/utils/url.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/** 直接当前页面跳转到指定url */
|
||||
export const jump = (url: string) => {
|
||||
window.location.href = url
|
||||
}
|
||||
|
||||
/** 在新标签页中跳转到指定url */
|
||||
export const jumpBlank = (url: string) => {
|
||||
window.open(url, "_blank")
|
||||
}
|
||||
|
||||
/** 将对象转换为url查询字符串 */
|
||||
export const queryFormat = (query: Record<string, any>) => {
|
||||
const params = new URLSearchParams(query)
|
||||
return params.toString() ? `?${params}` : ""
|
||||
}
|
||||
Reference in New Issue
Block a user