@ion299/sdk-react-native 0.1.0-beta.5 → 0.1.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/android/src/main/java/com/chatplatform/sdk/ChatSdkAudioPlayerModule.kt +201 -0
- package/android/src/main/java/com/chatplatform/sdk/ChatSdkPackage.kt +1 -0
- package/ios/ChatSdkAudioPlayer.m +25 -0
- package/ios/ChatSdkAudioPlayer.swift +193 -0
- package/lib/commonjs/audio/audioController.js +145 -0
- package/lib/commonjs/audio/audioController.js.map +1 -0
- package/lib/commonjs/components/AudioMessage.js +198 -0
- package/lib/commonjs/components/AudioMessage.js.map +1 -0
- package/lib/commonjs/components/MessageBubble.js +9 -0
- package/lib/commonjs/components/MessageBubble.js.map +1 -1
- package/lib/commonjs/native/NativeChatSdkAudioPlayer.js +28 -0
- package/lib/commonjs/native/NativeChatSdkAudioPlayer.js.map +1 -0
- package/lib/module/audio/audioController.js +140 -0
- package/lib/module/audio/audioController.js.map +1 -0
- package/lib/module/components/AudioMessage.js +193 -0
- package/lib/module/components/AudioMessage.js.map +1 -0
- package/lib/module/components/MessageBubble.js +9 -0
- package/lib/module/components/MessageBubble.js.map +1 -1
- package/lib/module/native/NativeChatSdkAudioPlayer.js +23 -0
- package/lib/module/native/NativeChatSdkAudioPlayer.js.map +1 -0
- package/lib/typescript/commonjs/audio/audioController.d.ts +25 -0
- package/lib/typescript/commonjs/audio/audioController.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/AudioMessage.d.ts +11 -0
- package/lib/typescript/commonjs/components/AudioMessage.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/MessageBubble.d.ts.map +1 -1
- package/lib/typescript/commonjs/native/NativeChatSdkAudioPlayer.d.ts +20 -0
- package/lib/typescript/commonjs/native/NativeChatSdkAudioPlayer.d.ts.map +1 -0
- package/lib/typescript/module/audio/audioController.d.ts +25 -0
- package/lib/typescript/module/audio/audioController.d.ts.map +1 -0
- package/lib/typescript/module/components/AudioMessage.d.ts +11 -0
- package/lib/typescript/module/components/AudioMessage.d.ts.map +1 -0
- package/lib/typescript/module/components/MessageBubble.d.ts.map +1 -1
- package/lib/typescript/module/native/NativeChatSdkAudioPlayer.d.ts +20 -0
- package/lib/typescript/module/native/NativeChatSdkAudioPlayer.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/audio/audioController.ts +144 -0
- package/src/components/AudioMessage.tsx +198 -0
- package/src/components/MessageBubble.tsx +6 -0
- package/src/native/NativeChatSdkAudioPlayer.ts +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useEffect","useState","ActivityIndicator","StyleSheet","Text","TouchableOpacity","View","audioController","jsx","_jsx","jsxs","_jsxs","attachmentKey","attachment","id","url","formatTime","millis","Number","isFinite","totalSeconds","Math","floor","minutes","seconds","toString","padStart","AudioMessage","isOutbound","theme","key","pb","setPb","getState","trackWidth","setTrackWidth","subscribe","isPlaying","state","isLoading","isError","duration","durationMillis","position","positionMillis","progress","min","accent","primaryColor","trackBg","timeColor","systemText","iconColor","onToggle","pause","play","onSeek","e","ratio","max","nativeEvent","locationX","seek","onTrackLayout","layout","width","timeLabel","style","styles","root","children","button","backgroundColor","onPress","activeOpacity","disabled","size","color","PauseIcon","PlayIcon","body","onLayout","trackWrap","track","trackFill","thumb","left","time","playTriangle","borderLeftColor","pauseWrap","pauseBar","BUTTON_SIZE","create","flexDirection","alignItems","gap","minWidth","paddingVertical","height","borderRadius","justifyContent","flexShrink","flex","top","marginLeft","fontSize","lineHeight","borderStyle","borderTopWidth","borderBottomWidth","borderLeftWidth","borderTopColor","borderBottomColor"],"sourceRoot":"..\\..\\..\\src","sources":["components/AudioMessage.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Dimensions, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
5
5
|
import { attachmentDisplayName } from "../attachmentUtils.js";
|
|
6
|
+
import { audioController } from "../audio/audioController.js";
|
|
7
|
+
import { AudioMessage } from "./AudioMessage.js";
|
|
6
8
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
9
|
export function MessageBubble({
|
|
8
10
|
message,
|
|
@@ -90,6 +92,13 @@ function AttachmentView({
|
|
|
90
92
|
})
|
|
91
93
|
});
|
|
92
94
|
}
|
|
95
|
+
if (attachment.type === 'audio' && audioController.isAvailable) {
|
|
96
|
+
return /*#__PURE__*/_jsx(AudioMessage, {
|
|
97
|
+
attachment: attachment,
|
|
98
|
+
isOutbound: isOutbound,
|
|
99
|
+
theme: theme
|
|
100
|
+
});
|
|
101
|
+
}
|
|
93
102
|
const nameColor = isOutbound ? theme.outboundText : theme.inboundText;
|
|
94
103
|
const sizeColor = isOutbound ? 'rgba(255,255,255,0.65)' : theme.systemText;
|
|
95
104
|
const displayName = attachmentDisplayName(attachment);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Dimensions","Image","StyleSheet","Text","TouchableOpacity","View","attachmentDisplayName","jsx","_jsx","jsxs","_jsxs","MessageBubble","message","theme","onButtonPress","onAttachmentPress","type","style","styles","systemRow","children","systemText","color","text","isOutbound","row","rowRight","rowLeft","bubble","outbound","backgroundColor","outboundBg","inbound","inboundBg","sender","name","senderName","primaryColor","attachments","length","map","att","i","AttachmentView","attachment","onPress","id","undefined","outboundText","inboundText","buttons","btn","BotButton","button","callback_data","serverMessageId","time","formatBytes","bytes","toFixed","disabled","activeOpacity","source","uri","url","image","resizeMode","nameColor","sizeColor","displayName","fileBlock","fileName","numberOfLines","size","fileSize","botButton","borderColor","botButtonText","BUBBLE_MAX_WIDTH","get","width","create","flexDirection","marginVertical","paddingHorizontal","justifyContent","maxWidth","minWidth","borderRadius","paddingTop","paddingBottom","borderBottomRightRadius","borderBottomLeftRadius","fontSize","fontWeight","marginBottom","lineHeight","alignSelf","marginTop","alignItems","textAlign","gap","height","borderWidth","paddingVertical"],"sourceRoot":"..\\..\\..\\src","sources":["components/MessageBubble.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,UAAU,EAAEC,KAAK,EAAEC,UAAU,EAAEC,IAAI,EAAEC,gBAAgB,EAAEC,IAAI,QAAQ,cAAc;AAC1F,SAASC,qBAAqB,QAAQ,uBAAoB;AAAA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;
|
|
1
|
+
{"version":3,"names":["React","Dimensions","Image","StyleSheet","Text","TouchableOpacity","View","attachmentDisplayName","audioController","AudioMessage","jsx","_jsx","jsxs","_jsxs","MessageBubble","message","theme","onButtonPress","onAttachmentPress","type","style","styles","systemRow","children","systemText","color","text","isOutbound","row","rowRight","rowLeft","bubble","outbound","backgroundColor","outboundBg","inbound","inboundBg","sender","name","senderName","primaryColor","attachments","length","map","att","i","AttachmentView","attachment","onPress","id","undefined","outboundText","inboundText","buttons","btn","BotButton","button","callback_data","serverMessageId","time","formatBytes","bytes","toFixed","disabled","activeOpacity","source","uri","url","image","resizeMode","isAvailable","nameColor","sizeColor","displayName","fileBlock","fileName","numberOfLines","size","fileSize","botButton","borderColor","botButtonText","BUBBLE_MAX_WIDTH","get","width","create","flexDirection","marginVertical","paddingHorizontal","justifyContent","maxWidth","minWidth","borderRadius","paddingTop","paddingBottom","borderBottomRightRadius","borderBottomLeftRadius","fontSize","fontWeight","marginBottom","lineHeight","alignSelf","marginTop","alignItems","textAlign","gap","height","borderWidth","paddingVertical"],"sourceRoot":"..\\..\\..\\src","sources":["components/MessageBubble.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NativeEventEmitter, NativeModules, TurboModuleRegistry } from 'react-native';
|
|
4
|
+
const MODULE_NAME = 'ChatSdkAudioPlayer';
|
|
5
|
+
function loadModule() {
|
|
6
|
+
try {
|
|
7
|
+
return TurboModuleRegistry.get(MODULE_NAME);
|
|
8
|
+
} catch {
|
|
9
|
+
return NativeModules[MODULE_NAME] ?? null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const moduleRef = loadModule();
|
|
13
|
+
export default moduleRef;
|
|
14
|
+
let emitter = null;
|
|
15
|
+
function getEmitter() {
|
|
16
|
+
if (!moduleRef) return null;
|
|
17
|
+
if (!emitter) emitter = new NativeEventEmitter(moduleRef);
|
|
18
|
+
return emitter;
|
|
19
|
+
}
|
|
20
|
+
export function onAudioState(handler) {
|
|
21
|
+
return getEmitter()?.addListener('ChatSdkAudioState', handler) ?? null;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=NativeChatSdkAudioPlayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","NativeModules","TurboModuleRegistry","MODULE_NAME","loadModule","get","moduleRef","emitter","getEmitter","onAudioState","handler","addListener"],"sourceRoot":"..\\..\\..\\src","sources":["native/NativeChatSdkAudioPlayer.ts"],"mappings":";;AAAA,SAASA,kBAAkB,EAAEC,aAAa,EAAEC,mBAAmB,QAAQ,cAAc;AA2BrF,MAAMC,WAAW,GAAG,oBAAoB;AAExC,SAASC,UAAUA,CAAA,EAAgB;EACjC,IAAI;IACF,OAAOF,mBAAmB,CAACG,GAAG,CAAOF,WAAW,CAAC;EACnD,CAAC,CAAC,MAAM;IACN,OAAQF,aAAa,CAACE,WAAW,CAAC,IAAyB,IAAI;EACjE;AACF;AAEA,MAAMG,SAAS,GAAGF,UAAU,CAAC,CAAC;AAE9B,eAAeE,SAAS;AAExB,IAAIC,OAAkC,GAAG,IAAI;AAE7C,SAASC,UAAUA,CAAA,EAA8B;EAC/C,IAAI,CAACF,SAAS,EAAE,OAAO,IAAI;EAC3B,IAAI,CAACC,OAAO,EAAEA,OAAO,GAAG,IAAIP,kBAAkB,CAACM,SAA6B,CAAC;EAC7E,OAAOC,OAAO;AAChB;AAEA,OAAO,SAASE,YAAYA,CAC1BC,OAAyC,EACf;EAC1B,OAAOF,UAAU,CAAC,CAAC,EAAEG,WAAW,CAAC,mBAAmB,EAAED,OAAO,CAAC,IAAI,IAAI;AACxE","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface AudioPlaybackState {
|
|
2
|
+
state: 'idle' | 'loading' | 'playing' | 'paused' | 'error';
|
|
3
|
+
positionMillis: number;
|
|
4
|
+
durationMillis: number;
|
|
5
|
+
}
|
|
6
|
+
type Listener = (state: AudioPlaybackState) => void;
|
|
7
|
+
declare class AudioController {
|
|
8
|
+
private listeners;
|
|
9
|
+
private states;
|
|
10
|
+
private activeKey;
|
|
11
|
+
private subscribed;
|
|
12
|
+
get isAvailable(): boolean;
|
|
13
|
+
private ensureSubscribed;
|
|
14
|
+
private handleEvent;
|
|
15
|
+
private setState;
|
|
16
|
+
getState(key: string): AudioPlaybackState;
|
|
17
|
+
subscribe(key: string, listener: Listener): () => void;
|
|
18
|
+
play(key: string, url: string, headers?: Record<string, string>): Promise<void>;
|
|
19
|
+
pause(key: string): Promise<void>;
|
|
20
|
+
seek(key: string, positionMillis: number): Promise<void>;
|
|
21
|
+
stop(key: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare const audioController: AudioController;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=audioController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioController.d.ts","sourceRoot":"","sources":["../../../../src/audio/audioController.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC1D,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;AAInD,cAAM,eAAe;IACnB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAQ;IAE1B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,WAAW;IAqCnB,OAAO,CAAC,QAAQ;IAKhB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB;IAIzC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI;IAehD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBnF,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQvC;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ChatAttachment } from '../types';
|
|
3
|
+
import type { ChatTheme } from '../theme';
|
|
4
|
+
interface Props {
|
|
5
|
+
attachment: ChatAttachment;
|
|
6
|
+
isOutbound: boolean;
|
|
7
|
+
theme: ChatTheme;
|
|
8
|
+
}
|
|
9
|
+
export declare function AudioMessage({ attachment, isOutbound, theme }: Props): React.JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=AudioMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/AudioMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAWlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,KAAK;IACb,UAAU,EAAE,cAAc,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,SAAS,CAAA;CACjB;AAcD,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,KAAK,qBAmFpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/MessageBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/MessageBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,cAAc,EAAc,WAAW,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,SAAS,CAAA;IAChB,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,KAAK,IAAI,CAAA;IACvE,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAAA;CACzD;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,EAAE,KAAK,qBAgFxF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EventSubscription, TurboModule } from 'react-native';
|
|
2
|
+
export type NativeAudioState = 'loading' | 'playing' | 'paused' | 'ended' | 'stopped' | 'error';
|
|
3
|
+
export interface AudioStateEvent {
|
|
4
|
+
key: string;
|
|
5
|
+
positionMillis: number;
|
|
6
|
+
durationMillis: number;
|
|
7
|
+
state: NativeAudioState;
|
|
8
|
+
}
|
|
9
|
+
export interface Spec extends TurboModule {
|
|
10
|
+
play(key: string, url: string, headers: Record<string, string>): Promise<void>;
|
|
11
|
+
pause(key: string): Promise<void>;
|
|
12
|
+
seek(key: string, positionMillis: number): Promise<void>;
|
|
13
|
+
stop(key: string): Promise<void>;
|
|
14
|
+
addListener(eventName: string): void;
|
|
15
|
+
removeListeners(count: number): void;
|
|
16
|
+
}
|
|
17
|
+
declare const moduleRef: Spec | null;
|
|
18
|
+
export default moduleRef;
|
|
19
|
+
export declare function onAudioState(handler: (event: AudioStateEvent) => void): EventSubscription | null;
|
|
20
|
+
//# sourceMappingURL=NativeChatSdkAudioPlayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeChatSdkAudioPlayer.d.ts","sourceRoot":"","sources":["../../../../src/native/NativeChatSdkAudioPlayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAElE,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,OAAO,GACP,SAAS,GACT,OAAO,CAAA;AAEX,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,gBAAgB,CAAA;CACxB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9E,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrC;AAYD,QAAA,MAAM,SAAS,aAAe,CAAA;AAE9B,eAAe,SAAS,CAAA;AAUxB,wBAAgB,YAAY,CAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GACxC,iBAAiB,GAAG,IAAI,CAE1B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface AudioPlaybackState {
|
|
2
|
+
state: 'idle' | 'loading' | 'playing' | 'paused' | 'error';
|
|
3
|
+
positionMillis: number;
|
|
4
|
+
durationMillis: number;
|
|
5
|
+
}
|
|
6
|
+
type Listener = (state: AudioPlaybackState) => void;
|
|
7
|
+
declare class AudioController {
|
|
8
|
+
private listeners;
|
|
9
|
+
private states;
|
|
10
|
+
private activeKey;
|
|
11
|
+
private subscribed;
|
|
12
|
+
get isAvailable(): boolean;
|
|
13
|
+
private ensureSubscribed;
|
|
14
|
+
private handleEvent;
|
|
15
|
+
private setState;
|
|
16
|
+
getState(key: string): AudioPlaybackState;
|
|
17
|
+
subscribe(key: string, listener: Listener): () => void;
|
|
18
|
+
play(key: string, url: string, headers?: Record<string, string>): Promise<void>;
|
|
19
|
+
pause(key: string): Promise<void>;
|
|
20
|
+
seek(key: string, positionMillis: number): Promise<void>;
|
|
21
|
+
stop(key: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare const audioController: AudioController;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=audioController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioController.d.ts","sourceRoot":"","sources":["../../../../src/audio/audioController.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC1D,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;AAInD,cAAM,eAAe;IACnB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAQ;IAE1B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,WAAW;IAqCnB,OAAO,CAAC,QAAQ;IAKhB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB;IAIzC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI;IAehD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBnF,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQvC;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ChatAttachment } from '../types';
|
|
3
|
+
import type { ChatTheme } from '../theme';
|
|
4
|
+
interface Props {
|
|
5
|
+
attachment: ChatAttachment;
|
|
6
|
+
isOutbound: boolean;
|
|
7
|
+
theme: ChatTheme;
|
|
8
|
+
}
|
|
9
|
+
export declare function AudioMessage({ attachment, isOutbound, theme }: Props): React.JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=AudioMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/AudioMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAWlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,KAAK;IACb,UAAU,EAAE,cAAc,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,SAAS,CAAA;CACjB;AAcD,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,KAAK,qBAmFpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/MessageBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/MessageBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,cAAc,EAAc,WAAW,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,SAAS,CAAA;IAChB,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,KAAK,IAAI,CAAA;IACvE,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAAA;CACzD;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,EAAE,KAAK,qBAgFxF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EventSubscription, TurboModule } from 'react-native';
|
|
2
|
+
export type NativeAudioState = 'loading' | 'playing' | 'paused' | 'ended' | 'stopped' | 'error';
|
|
3
|
+
export interface AudioStateEvent {
|
|
4
|
+
key: string;
|
|
5
|
+
positionMillis: number;
|
|
6
|
+
durationMillis: number;
|
|
7
|
+
state: NativeAudioState;
|
|
8
|
+
}
|
|
9
|
+
export interface Spec extends TurboModule {
|
|
10
|
+
play(key: string, url: string, headers: Record<string, string>): Promise<void>;
|
|
11
|
+
pause(key: string): Promise<void>;
|
|
12
|
+
seek(key: string, positionMillis: number): Promise<void>;
|
|
13
|
+
stop(key: string): Promise<void>;
|
|
14
|
+
addListener(eventName: string): void;
|
|
15
|
+
removeListeners(count: number): void;
|
|
16
|
+
}
|
|
17
|
+
declare const moduleRef: Spec | null;
|
|
18
|
+
export default moduleRef;
|
|
19
|
+
export declare function onAudioState(handler: (event: AudioStateEvent) => void): EventSubscription | null;
|
|
20
|
+
//# sourceMappingURL=NativeChatSdkAudioPlayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeChatSdkAudioPlayer.d.ts","sourceRoot":"","sources":["../../../../src/native/NativeChatSdkAudioPlayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAElE,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,OAAO,GACP,SAAS,GACT,OAAO,CAAA;AAEX,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,gBAAgB,CAAA;CACxB;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9E,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrC;AAYD,QAAA,MAAM,SAAS,aAAe,CAAA;AAE9B,eAAe,SAAS,CAAA;AAUxB,wBAAgB,YAAY,CAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GACxC,iBAAiB,GAAG,IAAI,CAE1B"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import AudioModule, {
|
|
2
|
+
onAudioState,
|
|
3
|
+
type AudioStateEvent,
|
|
4
|
+
} from '../native/NativeChatSdkAudioPlayer'
|
|
5
|
+
|
|
6
|
+
export interface AudioPlaybackState {
|
|
7
|
+
state: 'idle' | 'loading' | 'playing' | 'paused' | 'error'
|
|
8
|
+
positionMillis: number
|
|
9
|
+
durationMillis: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type Listener = (state: AudioPlaybackState) => void
|
|
13
|
+
|
|
14
|
+
const IDLE: AudioPlaybackState = { state: 'idle', positionMillis: 0, durationMillis: 0 }
|
|
15
|
+
|
|
16
|
+
class AudioController {
|
|
17
|
+
private listeners = new Map<string, Set<Listener>>()
|
|
18
|
+
private states = new Map<string, AudioPlaybackState>()
|
|
19
|
+
private activeKey: string | null = null
|
|
20
|
+
private subscribed = false
|
|
21
|
+
|
|
22
|
+
get isAvailable(): boolean {
|
|
23
|
+
return !!AudioModule
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private ensureSubscribed() {
|
|
27
|
+
if (this.subscribed || !AudioModule) return
|
|
28
|
+
this.subscribed = true
|
|
29
|
+
onAudioState((event) => this.handleEvent(event))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private handleEvent(event: AudioStateEvent) {
|
|
33
|
+
const prev = this.getState(event.key)
|
|
34
|
+
let next: AudioPlaybackState
|
|
35
|
+
|
|
36
|
+
switch (event.state) {
|
|
37
|
+
case 'loading':
|
|
38
|
+
next = { state: 'loading', positionMillis: 0, durationMillis: event.durationMillis }
|
|
39
|
+
break
|
|
40
|
+
case 'playing':
|
|
41
|
+
next = {
|
|
42
|
+
state: 'playing',
|
|
43
|
+
positionMillis: event.positionMillis,
|
|
44
|
+
durationMillis: event.durationMillis || prev.durationMillis,
|
|
45
|
+
}
|
|
46
|
+
break
|
|
47
|
+
case 'paused':
|
|
48
|
+
next = {
|
|
49
|
+
state: 'paused',
|
|
50
|
+
positionMillis: event.positionMillis,
|
|
51
|
+
durationMillis: event.durationMillis || prev.durationMillis,
|
|
52
|
+
}
|
|
53
|
+
break
|
|
54
|
+
case 'ended':
|
|
55
|
+
case 'stopped':
|
|
56
|
+
next = { state: 'idle', positionMillis: 0, durationMillis: event.durationMillis || prev.durationMillis }
|
|
57
|
+
if (this.activeKey === event.key) this.activeKey = null
|
|
58
|
+
break
|
|
59
|
+
case 'error':
|
|
60
|
+
default:
|
|
61
|
+
next = { state: 'error', positionMillis: 0, durationMillis: 0 }
|
|
62
|
+
if (this.activeKey === event.key) this.activeKey = null
|
|
63
|
+
break
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.setState(event.key, next)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private setState(key: string, state: AudioPlaybackState) {
|
|
70
|
+
this.states.set(key, state)
|
|
71
|
+
this.listeners.get(key)?.forEach((listener) => listener(state))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getState(key: string): AudioPlaybackState {
|
|
75
|
+
return this.states.get(key) ?? IDLE
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
subscribe(key: string, listener: Listener): () => void {
|
|
79
|
+
this.ensureSubscribed()
|
|
80
|
+
let set = this.listeners.get(key)
|
|
81
|
+
if (!set) {
|
|
82
|
+
set = new Set()
|
|
83
|
+
this.listeners.set(key, set)
|
|
84
|
+
}
|
|
85
|
+
set.add(listener)
|
|
86
|
+
listener(this.getState(key))
|
|
87
|
+
return () => {
|
|
88
|
+
set!.delete(listener)
|
|
89
|
+
if (set!.size === 0) this.listeners.delete(key)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async play(key: string, url: string, headers: Record<string, string> = {}): Promise<void> {
|
|
94
|
+
if (!AudioModule) return
|
|
95
|
+
this.ensureSubscribed()
|
|
96
|
+
|
|
97
|
+
if (this.activeKey && this.activeKey !== key) {
|
|
98
|
+
const prevKey = this.activeKey
|
|
99
|
+
const prev = this.getState(prevKey)
|
|
100
|
+
this.setState(prevKey, { state: 'idle', positionMillis: 0, durationMillis: prev.durationMillis })
|
|
101
|
+
}
|
|
102
|
+
this.activeKey = key
|
|
103
|
+
|
|
104
|
+
const current = this.getState(key)
|
|
105
|
+
if (current.state === 'idle' || current.state === 'error') {
|
|
106
|
+
this.setState(key, { ...current, state: 'loading', positionMillis: 0 })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
await AudioModule.play(key, url, headers)
|
|
111
|
+
} catch {
|
|
112
|
+
this.setState(key, { state: 'error', positionMillis: 0, durationMillis: 0 })
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async pause(key: string): Promise<void> {
|
|
117
|
+
if (!AudioModule) return
|
|
118
|
+
try {
|
|
119
|
+
await AudioModule.pause(key)
|
|
120
|
+
} catch {
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async seek(key: string, positionMillis: number): Promise<void> {
|
|
126
|
+
if (!AudioModule) return
|
|
127
|
+
try {
|
|
128
|
+
await AudioModule.seek(key, positionMillis)
|
|
129
|
+
} catch {
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async stop(key: string): Promise<void> {
|
|
135
|
+
if (!AudioModule) return
|
|
136
|
+
try {
|
|
137
|
+
await AudioModule.stop(key)
|
|
138
|
+
} catch {
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const audioController = new AudioController()
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
ActivityIndicator,
|
|
4
|
+
GestureResponderEvent,
|
|
5
|
+
LayoutChangeEvent,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
Text,
|
|
8
|
+
TouchableOpacity,
|
|
9
|
+
View,
|
|
10
|
+
} from 'react-native'
|
|
11
|
+
import { audioController, type AudioPlaybackState } from '../audio/audioController'
|
|
12
|
+
import type { ChatAttachment } from '../types'
|
|
13
|
+
import type { ChatTheme } from '../theme'
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
attachment: ChatAttachment
|
|
17
|
+
isOutbound: boolean
|
|
18
|
+
theme: ChatTheme
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function attachmentKey(attachment: ChatAttachment): string {
|
|
22
|
+
return attachment.id > 0 ? `a${attachment.id}` : `t${attachment.url}`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function formatTime(millis: number): string {
|
|
26
|
+
if (!Number.isFinite(millis) || millis <= 0) return '0:00'
|
|
27
|
+
const totalSeconds = Math.floor(millis / 1000)
|
|
28
|
+
const minutes = Math.floor(totalSeconds / 60)
|
|
29
|
+
const seconds = totalSeconds % 60
|
|
30
|
+
return `${minutes}:${seconds.toString().padStart(2, '0')}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function AudioMessage({ attachment, isOutbound, theme }: Props) {
|
|
34
|
+
const key = attachmentKey(attachment)
|
|
35
|
+
const [pb, setPb] = useState<AudioPlaybackState>(() => audioController.getState(key))
|
|
36
|
+
const [trackWidth, setTrackWidth] = useState(0)
|
|
37
|
+
|
|
38
|
+
useEffect(() => audioController.subscribe(key, setPb), [key])
|
|
39
|
+
|
|
40
|
+
const isPlaying = pb.state === 'playing'
|
|
41
|
+
const isLoading = pb.state === 'loading'
|
|
42
|
+
const isError = pb.state === 'error'
|
|
43
|
+
const duration = pb.durationMillis
|
|
44
|
+
const position = pb.positionMillis
|
|
45
|
+
const progress = duration > 0 ? Math.min(1, position / duration) : 0
|
|
46
|
+
|
|
47
|
+
const accent = isOutbound ? '#ffffff' : theme.primaryColor
|
|
48
|
+
const trackBg = isOutbound ? 'rgba(255,255,255,0.30)' : 'rgba(0,0,0,0.12)'
|
|
49
|
+
const timeColor = isOutbound ? 'rgba(255,255,255,0.75)' : theme.systemText
|
|
50
|
+
const iconColor = isOutbound ? theme.primaryColor : '#ffffff'
|
|
51
|
+
|
|
52
|
+
const onToggle = () => {
|
|
53
|
+
if (isPlaying) {
|
|
54
|
+
void audioController.pause(key)
|
|
55
|
+
} else {
|
|
56
|
+
void audioController.play(key, attachment.url)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const onSeek = (e: GestureResponderEvent) => {
|
|
61
|
+
if (duration <= 0 || trackWidth <= 0) return
|
|
62
|
+
const ratio = Math.max(0, Math.min(1, e.nativeEvent.locationX / trackWidth))
|
|
63
|
+
void audioController.seek(key, ratio * duration)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const onTrackLayout = (e: LayoutChangeEvent) => {
|
|
67
|
+
setTrackWidth(e.nativeEvent.layout.width)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const timeLabel = duration > 0
|
|
71
|
+
? `${formatTime(position)} / ${formatTime(duration)}`
|
|
72
|
+
: isError
|
|
73
|
+
? 'Не удалось воспроизвести'
|
|
74
|
+
: formatTime(position)
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<View style={styles.root}>
|
|
78
|
+
<TouchableOpacity
|
|
79
|
+
style={[styles.button, { backgroundColor: accent }]}
|
|
80
|
+
onPress={onToggle}
|
|
81
|
+
activeOpacity={0.8}
|
|
82
|
+
disabled={isLoading}
|
|
83
|
+
>
|
|
84
|
+
{isLoading ? (
|
|
85
|
+
<ActivityIndicator size="small" color={iconColor} />
|
|
86
|
+
) : isPlaying ? (
|
|
87
|
+
<PauseIcon color={iconColor} />
|
|
88
|
+
) : (
|
|
89
|
+
<PlayIcon color={iconColor} />
|
|
90
|
+
)}
|
|
91
|
+
</TouchableOpacity>
|
|
92
|
+
|
|
93
|
+
<View style={styles.body}>
|
|
94
|
+
<TouchableOpacity
|
|
95
|
+
activeOpacity={1}
|
|
96
|
+
onPress={onSeek}
|
|
97
|
+
onLayout={onTrackLayout}
|
|
98
|
+
style={styles.trackWrap}
|
|
99
|
+
>
|
|
100
|
+
<View style={[styles.track, { backgroundColor: trackBg }]}>
|
|
101
|
+
<View
|
|
102
|
+
style={[styles.trackFill, { backgroundColor: accent, width: `${progress * 100}%` }]}
|
|
103
|
+
/>
|
|
104
|
+
<View
|
|
105
|
+
style={[
|
|
106
|
+
styles.thumb,
|
|
107
|
+
{ backgroundColor: accent, left: `${progress * 100}%` },
|
|
108
|
+
]}
|
|
109
|
+
/>
|
|
110
|
+
</View>
|
|
111
|
+
</TouchableOpacity>
|
|
112
|
+
<Text style={[styles.time, { color: timeColor }]}>{timeLabel}</Text>
|
|
113
|
+
</View>
|
|
114
|
+
</View>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function PlayIcon({ color }: { color: string }) {
|
|
119
|
+
return <View style={[styles.playTriangle, { borderLeftColor: color }]} />
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function PauseIcon({ color }: { color: string }) {
|
|
123
|
+
return (
|
|
124
|
+
<View style={styles.pauseWrap}>
|
|
125
|
+
<View style={[styles.pauseBar, { backgroundColor: color }]} />
|
|
126
|
+
<View style={[styles.pauseBar, { backgroundColor: color }]} />
|
|
127
|
+
</View>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const BUTTON_SIZE = 40
|
|
132
|
+
|
|
133
|
+
const styles = StyleSheet.create({
|
|
134
|
+
root: {
|
|
135
|
+
flexDirection: 'row',
|
|
136
|
+
alignItems: 'center',
|
|
137
|
+
gap: 10,
|
|
138
|
+
minWidth: 200,
|
|
139
|
+
paddingVertical: 2,
|
|
140
|
+
},
|
|
141
|
+
button: {
|
|
142
|
+
width: BUTTON_SIZE,
|
|
143
|
+
height: BUTTON_SIZE,
|
|
144
|
+
borderRadius: BUTTON_SIZE / 2,
|
|
145
|
+
alignItems: 'center',
|
|
146
|
+
justifyContent: 'center',
|
|
147
|
+
flexShrink: 0,
|
|
148
|
+
},
|
|
149
|
+
body: {
|
|
150
|
+
flex: 1,
|
|
151
|
+
gap: 4,
|
|
152
|
+
},
|
|
153
|
+
trackWrap: {
|
|
154
|
+
paddingVertical: 8,
|
|
155
|
+
justifyContent: 'center',
|
|
156
|
+
},
|
|
157
|
+
track: {
|
|
158
|
+
height: 4,
|
|
159
|
+
borderRadius: 2,
|
|
160
|
+
},
|
|
161
|
+
trackFill: {
|
|
162
|
+
height: 4,
|
|
163
|
+
borderRadius: 2,
|
|
164
|
+
},
|
|
165
|
+
thumb: {
|
|
166
|
+
position: 'absolute',
|
|
167
|
+
top: -3,
|
|
168
|
+
width: 10,
|
|
169
|
+
height: 10,
|
|
170
|
+
borderRadius: 5,
|
|
171
|
+
marginLeft: -5,
|
|
172
|
+
},
|
|
173
|
+
time: {
|
|
174
|
+
fontSize: 11,
|
|
175
|
+
lineHeight: 14,
|
|
176
|
+
},
|
|
177
|
+
playTriangle: {
|
|
178
|
+
width: 0,
|
|
179
|
+
height: 0,
|
|
180
|
+
backgroundColor: 'transparent',
|
|
181
|
+
borderStyle: 'solid',
|
|
182
|
+
borderTopWidth: 7,
|
|
183
|
+
borderBottomWidth: 7,
|
|
184
|
+
borderLeftWidth: 12,
|
|
185
|
+
borderTopColor: 'transparent',
|
|
186
|
+
borderBottomColor: 'transparent',
|
|
187
|
+
marginLeft: 3,
|
|
188
|
+
},
|
|
189
|
+
pauseWrap: {
|
|
190
|
+
flexDirection: 'row',
|
|
191
|
+
gap: 4,
|
|
192
|
+
},
|
|
193
|
+
pauseBar: {
|
|
194
|
+
width: 4,
|
|
195
|
+
height: 14,
|
|
196
|
+
borderRadius: 1,
|
|
197
|
+
},
|
|
198
|
+
})
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Dimensions, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
|
|
3
3
|
import { attachmentDisplayName } from '../attachmentUtils'
|
|
4
|
+
import { audioController } from '../audio/audioController'
|
|
5
|
+
import { AudioMessage } from './AudioMessage'
|
|
4
6
|
import type { ChatAttachment, ChatButton, ChatMessage } from '../types'
|
|
5
7
|
import type { ChatTheme } from '../theme'
|
|
6
8
|
|
|
@@ -123,6 +125,10 @@ function AttachmentView({
|
|
|
123
125
|
)
|
|
124
126
|
}
|
|
125
127
|
|
|
128
|
+
if (attachment.type === 'audio' && audioController.isAvailable) {
|
|
129
|
+
return <AudioMessage attachment={attachment} isOutbound={isOutbound} theme={theme} />
|
|
130
|
+
}
|
|
131
|
+
|
|
126
132
|
const nameColor = isOutbound ? theme.outboundText : theme.inboundText
|
|
127
133
|
const sizeColor = isOutbound ? 'rgba(255,255,255,0.65)' : theme.systemText
|
|
128
134
|
const displayName = attachmentDisplayName(attachment)
|