⚠️
You are viewing the documentation for the LB Tablet Beta.
Custom Apps
See the custom apps exports for adding the app to the tablet. We recommend using our custom app template (opens in a new tab) to get started with creating custom apps.
Imported data
When the app gets loaded on the tablet, a few functions and data are imported into the globalThis object.
resourceName
The resource name of the app
appName
The name of the app
settings
The tablet settings
onNuiEvent
A function to listen for NUI events sent via SendCustomAppMessage
globalThis.onNuiEvent(event: string, callback: (data: any) => void): voidonSettingsChange
Listen for settings changes
globalThis.onSettingsChange(callback: (settings: any) => void): voidfetchNui
Fetch data from the script
globalThis.fetchNui(event: string, data?: any, scriptName?: string): Promise<any>setApp
Open another app
globalThis.setApp(app: string): voidcloseApp
Close the app
globalThis.closeApp(): voidsetPopUp
Show a popup
type PopUp = {
id?: number;
title: string;
description: string;
vertical?: boolean;
inputs?: PopUpInput[];
input?: PopUpInput;
textareas?: PopUpTextarea[];
textarea?: PopUpTextarea;
attachment?: {
src: string;
};
buttons: {
title: string;
cb?: () => void;
disabled?: boolean;
bold?: boolean;
color?: 'red' | 'blue';
}[];
};
globalThis.setPopUp(data: PopUp): voidsetFullScreenImage
Show a full screen image
globalThis.setFullScreenImage(src: string): voidsetContextMenu
Show a context menu
type Contextmenu = {
id?: number;
title?: string;
buttons: {
title: string;
color?: 'red' | 'blue';
disabled?: boolean;
cb?: () => void;
}[];
};
globalThis.setContextMenu(data: Contextmenu): voidsetControlCentreVisible
Show or hide the control centre
globalThis.setControlCentreVisible(visible: boolean): voidsetGallery
Select an image or video from the gallery
type GalleryData = {
id?: number;
includeVideos?: boolean;
includeImages?: boolean;
allowExternal?: boolean;
multiSelect?: boolean;
onSelect: (data: PhotoData) => void;
};
type PhotoData = {
id: number;
src: string;
timestamp?: number;
type?: 'string';
favourite?: boolean;
isVideo?: boolean;
size?: number;
duration?: number;
};
globalThis.setGallery(data: GalleryData): voidsetColorPicker
Select a color
type ColorPickerData = {
id?: number;
defaultColor?: string;
onSelect: (color: string) => void;
onClose?: (color: string) => void;
};
globalThis.setColorPicker(data: ColorPickerData): voidsetIndicatorVisible
Show or hide the indicator
globalThis.setIndicatorVisible(visible: boolean): voidsaveToGallery
saveToGallery: (url: string, size?: number, type?: 'screenshot' | 'selfie' | 'import', shouldLog?: boolean) => Promise<number | false>uploadMedia
uploadMedia: (uploadType: 'Video' | 'Image' | 'Audio', blob: Blob) => Promise<string>createGameRender
GameRender
interface GameRender {
quality: number
xOffset: number
yOffset: number
recorder: MediaRecorder | undefined
recording: boolean
destroyed: boolean
canvas: HTMLCanvasElement | null
gl: WebGLRenderingContext | null
program: WebGLProgram | null
paused: boolean
viewport: {
x: number
y: number
width: number
height: number
}
canvasSize: {
width: number
height: number
}
animationFrame: number | null
mainTexture: WebGLTexture | null
hasPrevFrame: boolean
prevTextures: WebGLTexture[]
prevBuffers: WebGLFramebuffer[]
pause(): void
resume(): void
resize(width: number, height: number): void
resizeByAspect(ratio: number): void
setQuality(quality: number): void
setXOffset(offset: number): void
setYOffset(offset: number): void
destroy(keepCanvas?: boolean): void
takePhoto(): Promise<Blob>
startRecording(cb: (blob: Blob) => void): MediaRecorder | undefined
render(): void
}createGameRender: (canvas: HTMLCanvasElement) => GameRender | undefinedgetMicrophoneStream
getMicrophoneStream: () => Promise<MediaStream | undefined>releaseMicrophoneStream
releaseMicrophoneStream: () => voidlistenToNearbyVoices
listenToNearbyVoices: (audioCtx: AudioContext, destination: MediaStreamAudioDestinationNode) => voidstopListeningToNearbyVoices
stopListeningToNearbyVoices: () => void