fix(chat): apply unlocked voice audio url
This commit is contained in:
@@ -66,8 +66,7 @@ describe("sendResponseToUiMessage", () => {
|
||||
it("maps locked voice messages without treating them as private text", () => {
|
||||
const message = sendResponseToUiMessage(
|
||||
makeResponse({
|
||||
audioUrl:
|
||||
"https://proapi.banlv-ai.com/audio/5198b93c-2915-406a.mp3",
|
||||
audioUrl: "",
|
||||
lockDetail: {
|
||||
locked: true,
|
||||
showContent: false,
|
||||
@@ -80,9 +79,7 @@ describe("sendResponseToUiMessage", () => {
|
||||
);
|
||||
|
||||
expect(message.content).toBe("AI reply");
|
||||
expect(message.audioUrl).toBe(
|
||||
"https://proapi.banlv-ai.com/audio/5198b93c-2915-406a.mp3",
|
||||
);
|
||||
expect(message.audioUrl).toBeUndefined();
|
||||
expect(message.locked).toBe(true);
|
||||
expect(message.lockReason).toBe("voice_message");
|
||||
expect(message.lockedPrivate).toBeUndefined();
|
||||
@@ -243,7 +240,7 @@ describe("localMessagesToUi", () => {
|
||||
type: "voice",
|
||||
content: "hidden voice transcript",
|
||||
createdAt: "2026-06-25T12:00:00.000Z",
|
||||
audioUrl: "https://example.com/voice.mp3",
|
||||
audioUrl: null,
|
||||
image: { type: null, url: null },
|
||||
lockDetail: {
|
||||
locked: true,
|
||||
@@ -257,7 +254,7 @@ describe("localMessagesToUi", () => {
|
||||
]);
|
||||
|
||||
expect(message.content).toBe("hidden voice transcript");
|
||||
expect(message.audioUrl).toBe("https://example.com/voice.mp3");
|
||||
expect(message.audioUrl).toBeUndefined();
|
||||
expect(message.locked).toBe(true);
|
||||
expect(message.lockReason).toBe("voice_message");
|
||||
expect(message.lockedPrivate).toBeUndefined();
|
||||
|
||||
@@ -59,6 +59,7 @@ function makeUnlockPrivateResponse(
|
||||
return UnlockPrivateResponse.from({
|
||||
unlocked: true,
|
||||
content: "unlocked content",
|
||||
audioUrl: "",
|
||||
reason: "ok",
|
||||
creditBalance: 90,
|
||||
creditsCharged: 10,
|
||||
@@ -740,7 +741,7 @@ describe("chatMachine transitions", () => {
|
||||
actor.stop();
|
||||
});
|
||||
|
||||
it("keeps voice message content unchanged after unlock succeeds", async () => {
|
||||
it("applies the real voice audio url after unlock succeeds", async () => {
|
||||
const actor = createActor(
|
||||
createTestChatMachine({
|
||||
historyMessages: [
|
||||
@@ -749,7 +750,6 @@ describe("chatMachine transitions", () => {
|
||||
content: "Original voice transcript.",
|
||||
isFromAI: true,
|
||||
date: "2026-06-29",
|
||||
audioUrl: "https://example.com/voice.mp3",
|
||||
locked: true,
|
||||
lockReason: "voice_message",
|
||||
privateMessageHint: "A voice message is waiting.",
|
||||
@@ -759,6 +759,7 @@ describe("chatMachine transitions", () => {
|
||||
messageId: "msg-voice-locked",
|
||||
response: makeUnlockPrivateResponse({
|
||||
content: "This response content must be ignored.",
|
||||
audioUrl: "https://example.com/unlocked-voice.mp3",
|
||||
}),
|
||||
},
|
||||
}),
|
||||
@@ -783,7 +784,7 @@ describe("chatMachine transitions", () => {
|
||||
{
|
||||
id: "msg-voice-locked",
|
||||
content: "Original voice transcript.",
|
||||
audioUrl: "https://example.com/voice.mp3",
|
||||
audioUrl: "https://example.com/unlocked-voice.mp3",
|
||||
locked: false,
|
||||
lockReason: null,
|
||||
privateMessageHint: null,
|
||||
@@ -802,7 +803,6 @@ describe("chatMachine transitions", () => {
|
||||
content: "",
|
||||
isFromAI: true,
|
||||
date: "2026-06-29",
|
||||
audioUrl: "https://example.com/voice.mp3",
|
||||
locked: true,
|
||||
lockReason: "voice_message",
|
||||
privateMessageHint: "A voice message is waiting.",
|
||||
@@ -855,6 +855,14 @@ describe("chatMachine transitions", () => {
|
||||
requiredCredits: 10,
|
||||
shortfallCredits: 7,
|
||||
});
|
||||
expect(actor.getSnapshot().context.messages).toMatchObject([
|
||||
{
|
||||
id: "msg-voice-locked",
|
||||
locked: true,
|
||||
lockReason: "voice_message",
|
||||
},
|
||||
]);
|
||||
expect(actor.getSnapshot().context.messages[0]?.audioUrl).toBeUndefined();
|
||||
expect(actor.getSnapshot().context.isUnlockingMessage).toBe(false);
|
||||
|
||||
actor.stop();
|
||||
|
||||
@@ -64,7 +64,11 @@ export const unlockMessageActor = fromPromise<
|
||||
if (unlockResult.data.unlocked) {
|
||||
const markResult = await chatRepo.markPrivateMessageUnlockedInLocal(
|
||||
input.messageId,
|
||||
unlockResult.data.lockDetail,
|
||||
{
|
||||
content: unlockResult.data.content,
|
||||
audioUrl: unlockResult.data.audioUrl,
|
||||
lockDetail: unlockResult.data.lockDetail,
|
||||
},
|
||||
);
|
||||
if (Result.isErr(markResult)) {
|
||||
log.warn("[chat-machine] mark unlocked local message failed", {
|
||||
|
||||
@@ -20,6 +20,7 @@ export function applySingleUnlockOutput(
|
||||
|
||||
return {
|
||||
...message,
|
||||
audioUrl: getUnlockedAudioUrl(message, output.response),
|
||||
locked: output.response.lockDetail.locked,
|
||||
lockReason: output.response.lockDetail.reason,
|
||||
imagePaywalled: message.imageUrl
|
||||
@@ -32,6 +33,15 @@ export function applySingleUnlockOutput(
|
||||
});
|
||||
}
|
||||
|
||||
function getUnlockedAudioUrl(
|
||||
message: UiMessage,
|
||||
response: UnlockPrivateResponse,
|
||||
): string | undefined {
|
||||
if (message.lockReason !== "voice_message") return message.audioUrl;
|
||||
if (response.audioUrl.length === 0) return message.audioUrl;
|
||||
return response.audioUrl;
|
||||
}
|
||||
|
||||
function shouldApplySingleUnlock(message: UiMessage, messageId: string): boolean {
|
||||
if (message.id !== messageId) return false;
|
||||
if (!message.isFromAI) return false;
|
||||
|
||||
Reference in New Issue
Block a user