mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-09-04 17:23:25 +00:00
ADD - mock garage and valet services
This commit is contained in:
+352
-77
@@ -24,13 +24,115 @@ let mockBankBalance = 24787
|
|||||||
let mockCashBalance = 2350
|
let mockCashBalance = 2350
|
||||||
let nextBankTransactionId = 7
|
let nextBankTransactionId = 7
|
||||||
const mockBankTransactions = [
|
const mockBankTransactions = [
|
||||||
{ id: 1, kind: 'transfer_in', amount: 3200, label: 'Sofia Turner', reference: 'mock-1', createdAt: Date.now() - 45 * 60 * 1000 },
|
{
|
||||||
{ id: 2, kind: 'transfer_out', amount: 680, label: 'Vincent Cole', reference: 'mock-2', createdAt: Date.now() - 5 * 60 * 60 * 1000 },
|
id: 1,
|
||||||
{ id: 3, kind: 'deposit', amount: 1250, label: '', reference: 'mock-3', createdAt: Date.now() - 25 * 60 * 60 * 1000 },
|
kind: 'transfer_in',
|
||||||
{ id: 4, kind: 'transfer_out', amount: 420, label: 'Maya Brooks', reference: 'mock-4', createdAt: Date.now() - 50 * 60 * 60 * 1000 },
|
amount: 3200,
|
||||||
{ id: 5, kind: 'withdrawal', amount: 300, label: '', reference: 'mock-5', createdAt: Date.now() - 76 * 60 * 60 * 1000 },
|
label: 'Sofia Turner',
|
||||||
{ id: 6, kind: 'transfer_in', amount: 950, label: 'Noah Bennett', reference: 'mock-6', createdAt: Date.now() - 120 * 60 * 60 * 1000 },
|
reference: 'mock-1',
|
||||||
|
createdAt: Date.now() - 45 * 60 * 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
kind: 'transfer_out',
|
||||||
|
amount: 680,
|
||||||
|
label: 'Vincent Cole',
|
||||||
|
reference: 'mock-2',
|
||||||
|
createdAt: Date.now() - 5 * 60 * 60 * 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
kind: 'deposit',
|
||||||
|
amount: 1250,
|
||||||
|
label: '',
|
||||||
|
reference: 'mock-3',
|
||||||
|
createdAt: Date.now() - 25 * 60 * 60 * 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
kind: 'transfer_out',
|
||||||
|
amount: 420,
|
||||||
|
label: 'Maya Brooks',
|
||||||
|
reference: 'mock-4',
|
||||||
|
createdAt: Date.now() - 50 * 60 * 60 * 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
kind: 'withdrawal',
|
||||||
|
amount: 300,
|
||||||
|
label: '',
|
||||||
|
reference: 'mock-5',
|
||||||
|
createdAt: Date.now() - 76 * 60 * 60 * 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
kind: 'transfer_in',
|
||||||
|
amount: 950,
|
||||||
|
label: 'Noah Bennett',
|
||||||
|
reference: 'mock-6',
|
||||||
|
createdAt: Date.now() - 120 * 60 * 60 * 1000,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
const mockGarageVehicles = [
|
||||||
|
{
|
||||||
|
id: 'vehicle-1',
|
||||||
|
plate: 'SKY 204',
|
||||||
|
vin: '1S9SKY204LS000001',
|
||||||
|
nickname: 'Midnight',
|
||||||
|
model: 'sultanrs',
|
||||||
|
name: 'Karin Sultan RS',
|
||||||
|
kind: 'car',
|
||||||
|
status: 'garaged',
|
||||||
|
location: 'Legion Square',
|
||||||
|
fuel: 82,
|
||||||
|
engine: 96,
|
||||||
|
body: 91,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vehicle-2',
|
||||||
|
plate: 'NOVA 77',
|
||||||
|
vin: '1S9NOVA77LS000002',
|
||||||
|
nickname: '',
|
||||||
|
model: 'comet6',
|
||||||
|
name: 'Pfister Comet S2',
|
||||||
|
kind: 'car',
|
||||||
|
status: 'out',
|
||||||
|
location: '',
|
||||||
|
fuel: 46,
|
||||||
|
engine: 88,
|
||||||
|
body: 73,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vehicle-3',
|
||||||
|
plate: 'SEA 911',
|
||||||
|
vin: '1S9SEA911LS000003',
|
||||||
|
nickname: 'Blue Current',
|
||||||
|
model: 'speeder',
|
||||||
|
name: 'Pegassi Speeder',
|
||||||
|
kind: 'boat',
|
||||||
|
status: 'garaged',
|
||||||
|
location: 'La Puerta Pier',
|
||||||
|
fuel: 67,
|
||||||
|
engine: 84,
|
||||||
|
body: 79,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vehicle-4',
|
||||||
|
plate: 'AIR 404',
|
||||||
|
vin: '1S9AIR404LS000004',
|
||||||
|
nickname: '',
|
||||||
|
model: 'maverick',
|
||||||
|
name: 'Buckingham Maverick',
|
||||||
|
kind: 'helicopter',
|
||||||
|
status: 'impounded',
|
||||||
|
location: 'Impound Heli',
|
||||||
|
fuel: 23,
|
||||||
|
engine: 58,
|
||||||
|
body: 44,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
let mockGarageValet = null
|
||||||
|
|
||||||
let contactSequence = 2
|
let contactSequence = 2
|
||||||
const contacts = [
|
const contacts = [
|
||||||
@@ -45,8 +147,13 @@ const contacts = [
|
|||||||
const attachmentAssets = {
|
const attachmentAssets = {
|
||||||
gif: new Set(['celebrate', 'hearts', 'party', 'thumbs_up', 'wow']),
|
gif: new Set(['celebrate', 'hearts', 'party', 'thumbs_up', 'wow']),
|
||||||
image: new Set([
|
image: new Set([
|
||||||
'camera-1', 'camera-2', 'camera-3', 'city-lights', 'desert-road',
|
'camera-1',
|
||||||
'ocean-air', 'sunset-drive',
|
'camera-2',
|
||||||
|
'camera-3',
|
||||||
|
'city-lights',
|
||||||
|
'desert-road',
|
||||||
|
'ocean-air',
|
||||||
|
'sunset-drive',
|
||||||
]),
|
]),
|
||||||
video: new Set(['city-loop', 'ocean-loop', 'sunset-loop']),
|
video: new Set(['city-loop', 'ocean-loop', 'sunset-loop']),
|
||||||
}
|
}
|
||||||
@@ -177,8 +284,26 @@ const darkChatProfile = {
|
|||||||
createdAt: '2026-08-01 21:20:00',
|
createdAt: '2026-08-01 21:20:00',
|
||||||
}
|
}
|
||||||
const darkChatPeers = [
|
const darkChatPeers = [
|
||||||
{ id: 2, darkId: 'dark:N0VA-41KQ', alias: 'Nova', originalAlias: 'Nova', avatarSeed: 142, activityVisible: true, isContact: true, blocked: false },
|
{
|
||||||
{ id: 3, darkId: 'dark:ECH0-77LM', alias: 'Echo', originalAlias: 'Echo', avatarSeed: 311, activityVisible: false, isContact: true, blocked: false },
|
id: 2,
|
||||||
|
darkId: 'dark:N0VA-41KQ',
|
||||||
|
alias: 'Nova',
|
||||||
|
originalAlias: 'Nova',
|
||||||
|
avatarSeed: 142,
|
||||||
|
activityVisible: true,
|
||||||
|
isContact: true,
|
||||||
|
blocked: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
darkId: 'dark:ECH0-77LM',
|
||||||
|
alias: 'Echo',
|
||||||
|
originalAlias: 'Echo',
|
||||||
|
avatarSeed: 311,
|
||||||
|
activityVisible: false,
|
||||||
|
isContact: true,
|
||||||
|
blocked: false,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
const darkChatConversations = [
|
const darkChatConversations = [
|
||||||
{
|
{
|
||||||
@@ -193,28 +318,51 @@ const darkChatConversations = [
|
|||||||
]
|
]
|
||||||
const darkChatMessages = [
|
const darkChatMessages = [
|
||||||
{
|
{
|
||||||
id: 'dc-message-00000000-0000-000000000001', conversationId: darkChatConversations[0].id,
|
id: 'dc-message-00000000-0000-000000000001',
|
||||||
direction: 'received', senderProfileId: 2, messageType: 'text', body: 'The east gate is clear. Are you close?',
|
conversationId: darkChatConversations[0].id,
|
||||||
reactions: {}, createdAt: '2026-08-06 22:42:00', readAt: '2026-08-06 22:43:00',
|
direction: 'received',
|
||||||
|
senderProfileId: 2,
|
||||||
|
messageType: 'text',
|
||||||
|
body: 'The east gate is clear. Are you close?',
|
||||||
|
reactions: {},
|
||||||
|
createdAt: '2026-08-06 22:42:00',
|
||||||
|
readAt: '2026-08-06 22:43:00',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'dc-message-00000000-0000-000000000002', conversationId: darkChatConversations[0].id,
|
id: 'dc-message-00000000-0000-000000000002',
|
||||||
direction: 'sent', senderProfileId: 1, messageType: 'text', body: 'Two minutes. Keep this channel quiet. 🟣',
|
conversationId: darkChatConversations[0].id,
|
||||||
reactions: { 2: '👍' }, createdAt: '2026-08-06 22:43:00', readAt: '2026-08-06 22:43:30',
|
direction: 'sent',
|
||||||
|
senderProfileId: 1,
|
||||||
|
messageType: 'text',
|
||||||
|
body: 'Two minutes. Keep this channel quiet. 🟣',
|
||||||
|
reactions: { 2: '👍' },
|
||||||
|
createdAt: '2026-08-06 22:43:00',
|
||||||
|
readAt: '2026-08-06 22:43:30',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'dc-message-00000000-0000-000000000003', conversationId: darkChatConversations[0].id,
|
id: 'dc-message-00000000-0000-000000000003',
|
||||||
direction: 'received', senderProfileId: 2, messageType: 'gif', body: '',
|
conversationId: darkChatConversations[0].id,
|
||||||
mediaPayload: 'https://media.giphy.com/media/ICOgUNjpvO0PC/giphy.gif', reactions: {}, createdAt: '2026-08-06 22:44:00', readAt: null,
|
direction: 'received',
|
||||||
|
senderProfileId: 2,
|
||||||
|
messageType: 'gif',
|
||||||
|
body: '',
|
||||||
|
mediaPayload: 'https://media.giphy.com/media/ICOgUNjpvO0PC/giphy.gif',
|
||||||
|
reactions: {},
|
||||||
|
createdAt: '2026-08-06 22:44:00',
|
||||||
|
readAt: null,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function darkChatBootstrap() {
|
function darkChatBootstrap() {
|
||||||
return {
|
return {
|
||||||
profile: darkChatProfile,
|
profile: darkChatProfile,
|
||||||
contacts: darkChatPeers.filter((peer) => peer.isContact).map((peer) => ({ ...peer, createdAt: '2026-08-03 22:12:00' })),
|
contacts: darkChatPeers
|
||||||
|
.filter((peer) => peer.isContact)
|
||||||
|
.map((peer) => ({ ...peer, createdAt: '2026-08-03 22:12:00' })),
|
||||||
conversations: darkChatConversations.map((conversation) => {
|
conversations: darkChatConversations.map((conversation) => {
|
||||||
const thread = darkChatMessages.filter((message) => message.conversationId === conversation.id)
|
const thread = darkChatMessages.filter(
|
||||||
|
(message) => message.conversationId === conversation.id,
|
||||||
|
)
|
||||||
const last = thread.at(-1)
|
const last = thread.at(-1)
|
||||||
return {
|
return {
|
||||||
id: conversation.id,
|
id: conversation.id,
|
||||||
@@ -224,7 +372,9 @@ function darkChatBootstrap() {
|
|||||||
lastMessage: last?.body ?? '',
|
lastMessage: last?.body ?? '',
|
||||||
lastMessageType: last?.messageType ?? 'system',
|
lastMessageType: last?.messageType ?? 'system',
|
||||||
lastMessageAt: last?.createdAt ?? conversation.createdAt,
|
lastMessageAt: last?.createdAt ?? conversation.createdAt,
|
||||||
unread: thread.filter((message) => message.direction === 'received' && !message.readAt).length,
|
unread: thread.filter(
|
||||||
|
(message) => message.direction === 'received' && !message.readAt,
|
||||||
|
).length,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
@@ -904,18 +1054,74 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
response.json({ success: true, data: bankingOverview() })
|
response.json({ success: true, data: bankingOverview() })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'banking:transfer') {
|
if (endpoint === 'garage:vehicles') {
|
||||||
|
response.json({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
system: 'jg',
|
||||||
|
valet: {
|
||||||
|
account: 'bank',
|
||||||
|
enabled: true,
|
||||||
|
price: 750,
|
||||||
|
vehicleTypes: {
|
||||||
|
bike: true,
|
||||||
|
boat: false,
|
||||||
|
car: true,
|
||||||
|
helicopter: false,
|
||||||
|
plane: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vehicles: mockGarageVehicles,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (endpoint === 'garage:valet-state') {
|
||||||
|
response.json({ success: true, data: mockGarageValet })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (endpoint === 'garage:valet-request') {
|
||||||
|
const vehicle = mockGarageVehicles.find(
|
||||||
|
(item) => item.plate === request.body.plate,
|
||||||
|
)
|
||||||
|
if (!vehicle || vehicle.status !== 'garaged') {
|
||||||
|
response.json({ success: false, error: 'vehicle_not_garaged' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!['car', 'bike'].includes(vehicle.kind)) {
|
||||||
|
response.json({ success: false, error: 'valet_vehicle_type' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mockGarageValet = {
|
||||||
|
canCancel: true,
|
||||||
|
cost: 750,
|
||||||
|
distance: 1240,
|
||||||
|
etaSeconds: 62,
|
||||||
|
orderId: 'mock-valet-1',
|
||||||
|
plate: vehicle.plate,
|
||||||
|
status: 'en_route',
|
||||||
|
vehicleName: vehicle.nickname || vehicle.name,
|
||||||
|
}
|
||||||
|
response.json({ success: true, data: mockGarageValet })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (endpoint === 'garage:valet-cancel') {
|
||||||
|
mockGarageValet = null
|
||||||
|
response.json({ success: true, data: null })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (endpoint === 'banking:transfer') {
|
||||||
const amount = Number(request.body.amount)
|
const amount = Number(request.body.amount)
|
||||||
if (!Number.isSafeInteger(amount) || amount <= 0) {
|
if (!Number.isSafeInteger(amount) || amount <= 0) {
|
||||||
response.json({ success: false, error: 'invalid_request' })
|
response.json({ success: false, error: 'invalid_request' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (mockBankBalance < amount) {
|
if (mockBankBalance < amount) {
|
||||||
response.json({ success: false, error: 'insufficient_funds' })
|
response.json({ success: false, error: 'insufficient_funds' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const kind = 'transfer_out'
|
const kind = 'transfer_out'
|
||||||
mockBankBalance -= amount
|
mockBankBalance -= amount
|
||||||
mockBankTransactions.unshift({
|
mockBankTransactions.unshift({
|
||||||
amount,
|
amount,
|
||||||
createdAt: Date.now(),
|
createdAt: Date.now(),
|
||||||
@@ -952,21 +1158,27 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:update-profile') {
|
if (endpoint === 'darkchat:update-profile') {
|
||||||
darkChatProfile.alias = String(request.body.alias ?? darkChatProfile.alias).trim()
|
darkChatProfile.alias = String(
|
||||||
darkChatProfile.notificationMode = request.body.notificationMode ?? 'private'
|
request.body.alias ?? darkChatProfile.alias,
|
||||||
|
).trim()
|
||||||
|
darkChatProfile.notificationMode =
|
||||||
|
request.body.notificationMode ?? 'private'
|
||||||
darkChatProfile.activityVisible = Boolean(request.body.activityVisible)
|
darkChatProfile.activityVisible = Boolean(request.body.activityVisible)
|
||||||
response.json({ success: true, data: darkChatProfile })
|
response.json({ success: true, data: darkChatProfile })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:start') {
|
if (endpoint === 'darkchat:start') {
|
||||||
const identifier = String(request.body.identifier ?? '').toUpperCase()
|
const identifier = String(request.body.identifier ?? '').toUpperCase()
|
||||||
const peer = darkChatPeers.find((item) => item.darkId.toUpperCase() === identifier)
|
const peer =
|
||||||
?? (identifier === 'DC-ECH0-77LM' ? darkChatPeers[1] : null)
|
darkChatPeers.find((item) => item.darkId.toUpperCase() === identifier) ??
|
||||||
|
(identifier === 'DC-ECH0-77LM' ? darkChatPeers[1] : null)
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
response.json({ success: false, error: 'profile_not_found' })
|
response.json({ success: false, error: 'profile_not_found' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let conversation = darkChatConversations.find((item) => item.peer.id === peer.id)
|
let conversation = darkChatConversations.find(
|
||||||
|
(item) => item.peer.id === peer.id,
|
||||||
|
)
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
conversation = {
|
conversation = {
|
||||||
id: `dc-conversation-${Date.now()}`,
|
id: `dc-conversation-${Date.now()}`,
|
||||||
@@ -983,22 +1195,38 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:thread') {
|
if (endpoint === 'darkchat:thread') {
|
||||||
const conversation = darkChatConversations.find((item) => item.id === request.body.conversationId)
|
const conversation = darkChatConversations.find(
|
||||||
|
(item) => item.id === request.body.conversationId,
|
||||||
|
)
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
response.json({ success: false, error: 'conversation_not_found' })
|
response.json({ success: false, error: 'conversation_not_found' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const thread = darkChatMessages.filter((message) => message.conversationId === conversation.id)
|
const thread = darkChatMessages.filter(
|
||||||
|
(message) => message.conversationId === conversation.id,
|
||||||
|
)
|
||||||
for (const message of thread) {
|
for (const message of thread) {
|
||||||
if (message.direction === 'received') message.readAt = message.readAt ?? new Date().toISOString()
|
if (message.direction === 'received')
|
||||||
|
message.readAt = message.readAt ?? new Date().toISOString()
|
||||||
}
|
}
|
||||||
response.json({ success: true, data: { conversation, messages: thread.map(({ mediaSecret, ...message }) => message) } })
|
response.json({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
conversation,
|
||||||
|
messages: thread.map(({ mediaSecret, ...message }) => message),
|
||||||
|
},
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:send') {
|
if (endpoint === 'darkchat:send') {
|
||||||
const conversation = darkChatConversations.find((item) => item.id === request.body.conversationId)
|
const conversation = darkChatConversations.find(
|
||||||
|
(item) => item.id === request.body.conversationId,
|
||||||
|
)
|
||||||
if (!conversation || conversation.peer.blocked) {
|
if (!conversation || conversation.peer.blocked) {
|
||||||
response.json({ success: false, error: conversation ? 'blocked' : 'conversation_not_found' })
|
response.json({
|
||||||
|
success: false,
|
||||||
|
error: conversation ? 'blocked' : 'conversation_not_found',
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const messageType = request.body.messageType ?? 'text'
|
const messageType = request.body.messageType ?? 'text'
|
||||||
@@ -1007,7 +1235,9 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
response.json({ success: false, error: 'invalid_message' })
|
response.json({ success: false, error: 'invalid_message' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const reply = darkChatMessages.find((message) => message.id === request.body.replyToId)
|
const reply = darkChatMessages.find(
|
||||||
|
(message) => message.id === request.body.replyToId,
|
||||||
|
)
|
||||||
const message = {
|
const message = {
|
||||||
id: `dc-message-${Date.now()}`,
|
id: `dc-message-${Date.now()}`,
|
||||||
conversationId: conversation.id,
|
conversationId: conversation.id,
|
||||||
@@ -1015,8 +1245,10 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
senderProfileId: darkChatProfile.id,
|
senderProfileId: darkChatProfile.id,
|
||||||
messageType,
|
messageType,
|
||||||
body,
|
body,
|
||||||
mediaPayload: messageType === 'gif' ? request.body.mediaPayload : undefined,
|
mediaPayload:
|
||||||
mediaSecret: messageType === 'voice' ? request.body.mediaPayload : undefined,
|
messageType === 'gif' ? request.body.mediaPayload : undefined,
|
||||||
|
mediaSecret:
|
||||||
|
messageType === 'voice' ? request.body.mediaPayload : undefined,
|
||||||
mediaMime: request.body.mediaMime,
|
mediaMime: request.body.mediaMime,
|
||||||
mediaDurationMs: request.body.mediaDurationMs,
|
mediaDurationMs: request.body.mediaDurationMs,
|
||||||
mediaWaveform: request.body.mediaWaveform,
|
mediaWaveform: request.body.mediaWaveform,
|
||||||
@@ -1032,25 +1264,42 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:media') {
|
if (endpoint === 'darkchat:media') {
|
||||||
const message = darkChatMessages.find((item) => item.id === request.body.messageId && item.messageType === 'voice')
|
const message = darkChatMessages.find(
|
||||||
response.json(message?.mediaSecret
|
(item) =>
|
||||||
? { success: true, data: { mime: message.mediaMime, payload: message.mediaSecret } }
|
item.id === request.body.messageId && item.messageType === 'voice',
|
||||||
: { success: false, error: 'message_not_found' })
|
)
|
||||||
|
response.json(
|
||||||
|
message?.mediaSecret
|
||||||
|
? {
|
||||||
|
success: true,
|
||||||
|
data: { mime: message.mediaMime, payload: message.mediaSecret },
|
||||||
|
}
|
||||||
|
: { success: false, error: 'message_not_found' },
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:react') {
|
if (endpoint === 'darkchat:react') {
|
||||||
const message = darkChatMessages.find((item) => item.id === request.body.messageId)
|
const message = darkChatMessages.find(
|
||||||
|
(item) => item.id === request.body.messageId,
|
||||||
|
)
|
||||||
if (message) {
|
if (message) {
|
||||||
const current = message.reactions[String(darkChatProfile.id)]
|
const current = message.reactions[String(darkChatProfile.id)]
|
||||||
if (current === request.body.reaction) delete message.reactions[String(darkChatProfile.id)]
|
if (current === request.body.reaction)
|
||||||
|
delete message.reactions[String(darkChatProfile.id)]
|
||||||
else message.reactions[String(darkChatProfile.id)] = request.body.reaction
|
else message.reactions[String(darkChatProfile.id)] = request.body.reaction
|
||||||
}
|
}
|
||||||
response.json({ success: Boolean(message), error: message ? undefined : 'message_not_found' })
|
response.json({
|
||||||
|
success: Boolean(message),
|
||||||
|
error: message ? undefined : 'message_not_found',
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:message-action') {
|
if (endpoint === 'darkchat:message-action') {
|
||||||
const index = darkChatMessages.findIndex((item) => item.id === request.body.messageId)
|
const index = darkChatMessages.findIndex(
|
||||||
if (index >= 0 && request.body.action === 'delete_me') darkChatMessages.splice(index, 1)
|
(item) => item.id === request.body.messageId,
|
||||||
|
)
|
||||||
|
if (index >= 0 && request.body.action === 'delete_me')
|
||||||
|
darkChatMessages.splice(index, 1)
|
||||||
else if (index >= 0 && request.body.action === 'delete_all') {
|
else if (index >= 0 && request.body.action === 'delete_all') {
|
||||||
darkChatMessages[index].messageType = 'system'
|
darkChatMessages[index].messageType = 'system'
|
||||||
darkChatMessages[index].body = 'message_deleted'
|
darkChatMessages[index].body = 'message_deleted'
|
||||||
@@ -1060,38 +1309,59 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:update-conversation') {
|
if (endpoint === 'darkchat:update-conversation') {
|
||||||
const conversation = darkChatConversations.find((item) => item.id === request.body.conversationId)
|
const conversation = darkChatConversations.find(
|
||||||
|
(item) => item.id === request.body.conversationId,
|
||||||
|
)
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
conversation.disappearingSeconds = Number(request.body.disappearingSeconds)
|
conversation.disappearingSeconds = Number(
|
||||||
conversation.notificationsEnabled = Boolean(request.body.notificationsEnabled)
|
request.body.disappearingSeconds,
|
||||||
|
)
|
||||||
|
conversation.notificationsEnabled = Boolean(
|
||||||
|
request.body.notificationsEnabled,
|
||||||
|
)
|
||||||
conversation.readReceipts = Boolean(request.body.readReceipts)
|
conversation.readReceipts = Boolean(request.body.readReceipts)
|
||||||
darkChatMessages.push({
|
darkChatMessages.push({
|
||||||
id: `dc-system-${Date.now()}`, conversationId: conversation.id, direction: 'received',
|
id: `dc-system-${Date.now()}`,
|
||||||
messageType: 'system', body: `timer_changed:${conversation.disappearingSeconds}`,
|
conversationId: conversation.id,
|
||||||
reactions: {}, createdAt: new Date().toISOString().slice(0, 19).replace('T', ' '),
|
direction: 'received',
|
||||||
|
messageType: 'system',
|
||||||
|
body: `timer_changed:${conversation.disappearingSeconds}`,
|
||||||
|
reactions: {},
|
||||||
|
createdAt: new Date().toISOString().slice(0, 19).replace('T', ' '),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
response.json({ success: Boolean(conversation) })
|
response.json({ success: Boolean(conversation) })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:add-contact' || endpoint === 'darkchat:remove-contact') {
|
if (
|
||||||
const conversation = darkChatConversations.find((item) => item.id === request.body.conversationId)
|
endpoint === 'darkchat:add-contact' ||
|
||||||
|
endpoint === 'darkchat:remove-contact'
|
||||||
|
) {
|
||||||
|
const conversation = darkChatConversations.find(
|
||||||
|
(item) => item.id === request.body.conversationId,
|
||||||
|
)
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
conversation.peer.isContact = endpoint === 'darkchat:add-contact'
|
conversation.peer.isContact = endpoint === 'darkchat:add-contact'
|
||||||
if (request.body.alias) conversation.peer.alias = String(request.body.alias)
|
if (request.body.alias)
|
||||||
|
conversation.peer.alias = String(request.body.alias)
|
||||||
}
|
}
|
||||||
response.json({ success: Boolean(conversation) })
|
response.json({ success: Boolean(conversation) })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:block') {
|
if (endpoint === 'darkchat:block') {
|
||||||
const conversation = darkChatConversations.find((item) => item.id === request.body.conversationId)
|
const conversation = darkChatConversations.find(
|
||||||
|
(item) => item.id === request.body.conversationId,
|
||||||
|
)
|
||||||
if (conversation) conversation.peer.blocked = Boolean(request.body.blocked)
|
if (conversation) conversation.peer.blocked = Boolean(request.body.blocked)
|
||||||
response.json({ success: Boolean(conversation) })
|
response.json({ success: Boolean(conversation) })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (endpoint === 'darkchat:clear') {
|
if (endpoint === 'darkchat:clear') {
|
||||||
for (let index = darkChatMessages.length - 1; index >= 0; index -= 1) {
|
for (let index = darkChatMessages.length - 1; index >= 0; index -= 1) {
|
||||||
if (darkChatMessages[index].conversationId === request.body.conversationId) darkChatMessages.splice(index, 1)
|
if (
|
||||||
|
darkChatMessages[index].conversationId === request.body.conversationId
|
||||||
|
)
|
||||||
|
darkChatMessages.splice(index, 1)
|
||||||
}
|
}
|
||||||
response.json({ success: true })
|
response.json({ success: true })
|
||||||
return
|
return
|
||||||
@@ -1127,14 +1397,16 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
if (endpoint === 'messages:gifs') {
|
if (endpoint === 'messages:gifs') {
|
||||||
const offset = Math.max(0, Number(request.body.offset ?? 0))
|
const offset = Math.max(0, Number(request.body.offset ?? 0))
|
||||||
const pageSize = 6
|
const pageSize = 6
|
||||||
const results = gifMocks.slice(offset, offset + pageSize).map(([id, title]) => ({
|
const results = gifMocks
|
||||||
height: 200,
|
.slice(offset, offset + pageSize)
|
||||||
id,
|
.map(([id, title]) => ({
|
||||||
previewUrl: `https://media.giphy.com/media/${id}/200w.gif`,
|
height: 200,
|
||||||
title,
|
id,
|
||||||
url: `https://media.giphy.com/media/${id}/giphy.gif`,
|
previewUrl: `https://media.giphy.com/media/${id}/200w.gif`,
|
||||||
width: 200,
|
title,
|
||||||
}))
|
url: `https://media.giphy.com/media/${id}/giphy.gif`,
|
||||||
|
width: 200,
|
||||||
|
}))
|
||||||
response.json({
|
response.json({
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
@@ -1174,7 +1446,8 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
message.sender_number === number || message.recipient_number === number,
|
message.sender_number === number || message.recipient_number === number,
|
||||||
)
|
)
|
||||||
for (const message of thread) {
|
for (const message of thread) {
|
||||||
if (message.direction === 'received') message.read_at = message.read_at ?? '2026-08-06 13:06:00'
|
if (message.direction === 'received')
|
||||||
|
message.read_at = message.read_at ?? '2026-08-06 13:06:00'
|
||||||
}
|
}
|
||||||
response.json({
|
response.json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -1231,10 +1504,9 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
created_at: new Date().toISOString().slice(0, 19).replace('T', ' '),
|
created_at: new Date().toISOString().slice(0, 19).replace('T', ' '),
|
||||||
direction: 'sent',
|
direction: 'sent',
|
||||||
id: `sms-${Date.now()}`,
|
id: `sms-${Date.now()}`,
|
||||||
media_duration_ms:
|
media_duration_ms: ['voice', 'video'].includes(messageType)
|
||||||
['voice', 'video'].includes(messageType)
|
? (request.body.mediaDurationMs ?? null)
|
||||||
? request.body.mediaDurationMs ?? null
|
: null,
|
||||||
: null,
|
|
||||||
media_mime:
|
media_mime:
|
||||||
messageType === 'voice'
|
messageType === 'voice'
|
||||||
? request.body.mediaMime
|
? request.body.mediaMime
|
||||||
@@ -1296,7 +1568,10 @@ app.post('/api/:endpoint', (request, response) => {
|
|||||||
if (contact) {
|
if (contact) {
|
||||||
contact.name = name
|
contact.name = name
|
||||||
contact.phone_number = phoneNumber
|
contact.phone_number = phoneNumber
|
||||||
contact.updated_at = new Date().toISOString().slice(0, 19).replace('T', ' ')
|
contact.updated_at = new Date()
|
||||||
|
.toISOString()
|
||||||
|
.slice(0, 19)
|
||||||
|
.replace('T', ' ')
|
||||||
} else {
|
} else {
|
||||||
const now = new Date().toISOString().slice(0, 19).replace('T', ' ')
|
const now = new Date().toISOString().slice(0, 19).replace('T', ' ')
|
||||||
contact = {
|
contact = {
|
||||||
|
|||||||
Reference in New Issue
Block a user