-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathclient.lua
More file actions
150 lines (123 loc) · 4.37 KB
/
client.lua
File metadata and controls
150 lines (123 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
-- ══════════════════════════════════════════════════════════════
-- uv-books · client.lua
-- Supports: QBCore, QBox (qbx_core), ox_lib notifications
-- ══════════════════════════════════════════════════════════════
local MAX_PAGES = 20
local MAX_CHARS = 800
local isWriting = false
-- ── Framework detection ──────────────────────────────────────
local Framework = nil
local QBCore = nil
CreateThread(function()
if GetResourceState("qbx_core") == "started" then
Framework = "qbx"
elseif GetResourceState("qb-core") == "started" then
Framework = "qb"
QBCore = exports["qb-core"]:GetCoreObject()
end
end)
-- ── Helper: client-side notification ─────────────────────────
local function Notify(msg, nType)
if GetResourceState("ox_lib") == "started" then
exports.ox_lib:notify({
description = msg,
type = nType or "info",
})
elseif Framework == "qb" and QBCore then
QBCore.Functions.Notify(msg, nType)
else
print("[uv-books] " .. (nType or "info") .. ": " .. msg)
end
end
-- ── Open the book writer NUI ──
RegisterNetEvent("uv-books:client:startWriting", function()
if isWriting then return end
isWriting = true
SetNuiFocus(true, true)
SendNUIMessage({ action = "openBookWriter" })
Citizen.CreateThread(function()
local ticks = 0
while isWriting and ticks < 10 do
Citizen.Wait(500)
if isWriting then SetNuiFocus(true, true) end
ticks = ticks + 1
end
end)
end)
-- ── Open the book reader NUI ──
RegisterNetEvent("uv-books:client:readBook", function(info, page)
if not info then
Notify("This book seems corrupted.", "error")
return
end
if isWriting then return end
isWriting = true
SetNuiFocus(true, true)
SendNUIMessage({
action = "openBookReader",
info = info,
page = page or 1
})
Citizen.CreateThread(function()
local ticks = 0
while isWriting and ticks < 10 do
Citizen.Wait(500)
if isWriting then SetNuiFocus(true, true) end
ticks = ticks + 1
end
end)
end)
-- ── ESC detection ──
local lastEsc = 0
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if isWriting then
local now = GetGameTimer()
if (now - lastEsc) > 600 then
if IsControlJustPressed(0, 202) or IsControlJustPressed(0, 322) then
lastEsc = now
SendNUIMessage({ action = "escPressed" })
end
end
end
end
end)
-- ── NUI Callbacks ──
RegisterNUICallback("draftSaved", function(data, cb)
cb("ok")
end)
RegisterNUICallback("bookPublished", function(data, cb)
cb("ok")
if not data then return end
local pages = {}
for i = 1, MAX_PAGES do
local raw = data.pages[i] or data.pages[tostring(i)] or data.pages[i - 1] or ""
if type(raw) ~= "string" then raw = "" end
if string.len(raw) > MAX_CHARS then raw = string.sub(raw, 1, MAX_CHARS) end
pages[i] = raw
end
local bookDraft = {
title = type(data.title) == "string" and data.title or "Untitled Book",
pages = pages,
signed = data.signed == true,
signature = type(data.signature) == "string" and data.signature or ""
}
TriggerServerEvent("uv-books:server:createBook", bookDraft)
isWriting = false
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
end)
RegisterNUICallback("bookClosed", function(data, cb)
isWriting = false
SetNuiFocus(false, false)
SetNuiFocusKeepInput(false)
cb("ok")
end)
-- ── Useable item (server handles routing, but keep client events for compat) ──
RegisterNetEvent("uv-books:client:nextPage", function(data)
-- no-op: reader is now handled in NUI
end)
RegisterNetEvent("uv-books:client:prevPage", function(data)
-- no-op: reader is now handled in NUI
end)