Skip to main content

Custom apps

Config

LB Phone allows you to add apps that either have a UI or simply trigger functions when opening the app. To add an app that simply triggers a function upon opening it, go to lb-phone/config/config.lua and add the app to the Config.CustomApps table, like this:

lb-phone/config/config.lua
Config.CustomApps = {
["app_identifier"] = { -- do not have any spaces in this name
name = "App Name", -- the name of the app
description = "App Description", -- the description of the app
developer = "LB Phone", -- OPTIONAL the developer of the app
defaultApp = true, -- OPTIONAL if set to true, app should be added without having to download it,
game = false -- OPTIONAL if set to true, app will be added to the game section
size = 59812, -- OPTIONAL in kB
images = {"https://example.com/photo.jpg"}, -- OPTIONAL array of images for the app on the app store
ui = "resource-name/ui/index.html", -- OPTIONAL
icon = "https://cfx-nui-" .. GetCurrentResourceName() .. "/ui/icon.png", -- OPTIONAL app icon
price = 0, -- OPTIONAL, Make players pay with in-game money to download the app
landscape = false, -- OPTIONAL, if set to true, the app will be displayed in landscape mode
keepOpen = true, -- OPTIONAL, if set to true, the app will not close when the player opens the app (only works if ui is not defined)
onUse = function() -- OPTIONAL function to be called when the app is opened
-- do something
end,
onServerUse = function(source) -- OPTIONAL server side function to be called when the app is opened
-- do something
end
}
}

Custom app using UI

If you want to use a custom UI for your app, you need to create a seperate script and provide the path of the HTML file and send it as ui.

The recommended way to create an app with UI is to create it using exports. We have template apps that you can use for reference.

Adding the app

To add the app, use the following export:

client.lua
local added, errorMessage = exports["lb-phone"]:AddCustomApp({
identifier = "test-app",
name = "Test App",
description = "This is a test app",
ui = GetCurrentResourceName() .. "/ui/index.html" -- this is the path to the HTML file,
})

if not added then
print("Could not add app:", errorMessage)
end

Removing the app

To remove the app, use the following export:

client.lua
local removed, errorMessage = exports["lb-phone"]:RemoveCustomApp("test-app")

if not removed then
print("Could not remove app:", errorMessage)
end

Sending a message to the UI

To send a message to the UI, you need to use the SendCustomAppMessage export instead of using SendNUIMessage. You would listen for it the same way in the frontend. Here's how to use it:

client.lua
exports["lb-phone"]:SendCustomAppMessage("test-app", {
message = "Hello world!"
})

Imported JS functions

When the app gets loaded on the phone, a few functions are imported into the app. These functions are:

fetchNui(event, data?, scriptName?)

fetchNui("getDirection").then((direction) => {
console.log(direction)
})

setPopUp(data)

setPopUp({
title: "Popup Menu",
description: "Confirm your choice",
input: {
type: "text", //Any HTML input type
placeholder: "Enter your name",
value: "John Doe",
minCharacters: 3,
maxCharacters: 20,
onChange: (value) => {
console.log(value)
}
// Any other input attributes
},
buttons: [
{
title: "Cancel",
color: "red",
cb: () => {
console.log("Cancel")
}
},
{
title: "Confirm",
color: "blue",
cb: () => {
console.log("Confirm")
}
}
]
})

setContextMenu(data)

setContextMenu({
title: "Context menu",
buttons: [
{
title: "Phone Notification",
color: "blue",
cb: () => {
sendNotification({ title: notificationText })
}
},
{
title: "GTA Notification",
color: "red",
cb: () => {
fetchNui("drawNotification", { message: notificationText })
}
}
]
})

setContactModal(phoneNumber)

setContactModal("1234567890")

selectGallery(data)

selectGallery({
includeVideos: true,
includeImages: true,
cb: (data) => {
setPopUp({
title: "Selected media",
attachment: data,
buttons: [
{
title: "OK"
}
]
})
}
})

selectGIF(cb)

selectGIF((gif) => {
console.log(gif)
})

selectEmoji(cb)

selectEmoji((emoji) => {
console.log(emoji)
})

getSettings()

getSettings().then((settings) => {
let theme = settings.display.theme
console.log(theme)
})

getLocale(path, format?)

getLocale("BACKEND.CAMERA.TAKE_PHOTO", { key: "Enter" }).then((locale) => {
console.log(locale)
})

sendNotification(data)

See SendNotification for more information.

sendNotification({ title: "Notification Text" })

onSettingsChange(cb)

onSettingsChange((settings) => {
let theme = settings.display.theme
console.log(theme)
})

useCamera(cb, options?)

useCamera(
(url) => {
console.log(url)
},
{
default: {
type: "Photo", // 'Photo' | 'Video' | 'Landscape'
flash: false,
camera: "rear" // 'rear' | 'front'
},
permissions: {
toggleFlash: true,
flipCamera: true,
takePhoto: true,
takeVideo: true,
takeLandscapePhoto: true
}
}
)