### Install and Run Documentation Website Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/Silkui/CLAUDE.md Commands to install dependencies, start a development server, build for production, and preview the production build of the Vue 3 documentation website. ```bash cd docs-vue npm install npm run dev npm run build npm run preview ``` -------------------------------- ### Configure and Get MySQL SSL Settings with MysqlSslApi Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/News/NewsServer/mysqlclient-ffi/doc/feature_api.md This example illustrates how to configure and retrieve SSL settings for a MySQL connection using MysqlSslApi. It demonstrates setting SSL parameters, getting the current SSL cipher, checking if the SSL session was reused, and managing SSL session data. It also includes assertions for the expected return values. ```Cangjie import mysqlclient_ffi.* import std.unittest.* import std.unittest.testmacro.* main():Int64{ // 初始化数据库驱动 let mysqlDriver: MysqlDriver = MysqlDriver("mysql") // 通过connectionString和选项打开数据源 let mysqlDatasource: MysqlDatasource = mysqlDriver.open( "HOST=127.0.0.1;USER=root;PASSWD=123;DB=mysql;PORT=3306;UNIX_SOCKET=;CLIENT_FLAG=0", Array<(String, String)>() ) // 返回一个可用的链接 let mysqlConnection: MysqlConnection = mysqlDatasource.connect() let mysqlSslApi: MysqlSslApi = MysqlSslApi(mysqlConnection) var isBool: Bool = mysqlSslApi.mysqlSslSet("", "", "", "", "") @Assert(false, isBool) var strCipher: String = mysqlSslApi.mysqlGetSslCipher() @Assert("", strCipher) isBool = mysqlSslApi.mysqlGetSslSessionReused() @Assert(false, isBool) mysqlSslApi.mysqlGetSslSessionData(0, CPointer()) // Assuming UInt32 is a placeholder for a valid type isBool = mysqlSslApi.mysqlFreeSslSessionData(CPointer()) // Assuming Unit is a placeholder for a valid type @Assert(true, isBool) mysqlConnection.close() } ``` -------------------------------- ### Grid Layout with ForEach in Cangjie Source: https://context7.com/piagari/reference/llms.txt Illustrates creating grid-based layouts using the Grid component and dynamically generating UI elements with ForEach in Cangjie. This example displays a grid of buttons. ```cangjie package ohos_app_cangjie_entry import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* import std.collection.* @Entry @Component class GridExample { @State var items: ArrayList = ArrayList( Keyboards.Seven, Keyboards.Eight, Keyboards.Nine, Keyboards.Divide, Keyboards.Four, Keyboards.Five, Keyboards.Six, Keyboards.Multiply, Keyboards.One, Keyboards.Two, Keyboards.Three, Keyboards.Reduce, Keyboards.Zero, Keyboards.Dot, Keyboards.Clear, Keyboards.Eval ) func build() { RelativeContainer { Grid { ForEach(items, itemGeneratorFunc: { entity: ButtonEntity, index: Int => GridItem { Button(entity.text) .shape(ShapeType.Normal) .stateEffect(true) .borderRadius(8) .width(100.percent) .height(100.percent) .onClick({ e => entity.onPress() }) .fontWeight(FontWeight.Medium) .fontColor(entity.textColor) .fontSize(24) .backgroundColor(entity.bgColor) } }) } .id('LAY_KEYBOARD') .rowsTemplate('1fr 1fr 1fr 1fr') // 4 equal rows .columnsTemplate('1fr 1fr 1fr 1fr') // 4 equal columns .columnsGap(8) .rowsGap(8) .padding(16) .width(100.percent) .height(50.percent) } .height(100.percent) .width(100.percent) } } ``` -------------------------------- ### Concurrency with spawn and launch in Cangjie Source: https://context7.com/piagari/reference/llms.txt Demonstrates creating background tasks using `spawn` and updating the UI thread safely with `launch`. It includes handling cancellation and final UI state updates. Dependencies include `ohos.base`, `ohos.component`, `ohos.concurrency`, `ohos.state_manage`, `ohos.state_macro_manage`, and `std.sync`. ```cangjie package ohos_app_cangjie_entry import ohos.base.* import ohos.component.* import ohos.concurrency.launch import ohos.state_manage.* import ohos.state_macro_manage.* import std.sync.* @Entry @Component class AsyncExample { @State var input: String = '' @State var output: String = '' var taskThread: Option> = None let llm = LLM(url: '...', key: '...', model: '...') func execute() { let text = input input = '' // Create background task with spawn taskThread = spawn { llm.chats(text) { slice: String => // Check for cancellation if (Thread.currentThread.hasPendingCancellation) { return false } // Update UI on main thread with launch launch { output += slice } return true } // After completion, update on main thread launch { // Finalize UI state } } } func stopTask() { if (let Some(future) <- taskThread) { future.cancel() future.get() // Wait for cancellation taskThread = None } } func build() { Column { TextInput(text: input) .onChange { value => input = value } Text(output) Row { Button("Send").onClick { execute() } Button("Stop").onClick { stopTask() } } } } } ``` -------------------------------- ### State Management with @Observed and @Publish in Cangjie Source: https://context7.com/piagari/reference/llms.txt Demonstrates how to manage complex state objects using @Observed class decorators and @Publish property decorators in Cangjie. Changes to published properties automatically update UI components. This example shows a calculator's state management. ```cangjie package ohos_app_cangjie_entry.entity import ohos.state_macro_manage.* import ohos.state_manage.* import std.collection.* @Observed public class DynamicParam { @Publish public var expressionText: String = "0" @Publish public var resultText: String = "0" @Publish public var expressionTextSize: Int64 = 40 @Publish public var resultTextSize: Int64 = 68 public func push(text: String) { if (expressionText == "0" && text != ".") { expressionText = text } else { expressionText = expressionText + text } // @Publish triggers automatic UI updates } public func clear() { expressionText = "0" resultText = "0" } public func calculate() { // Perform calculation and update resultText resultText = evaluateExpression(expressionText) } } // Usage in component: @Entry @Component class CalculatorView { @State var dynamicParam: DynamicParam = DynamicParam() func build() { Column { Text(dynamicParam.expressionText) .fontSize(dynamicParam.expressionTextSize) Text(dynamicParam.resultText) .fontSize(dynamicParam.resultTextSize) Button("7").onClick({ e => dynamicParam.push("7") }) Button("C").onClick({ e => dynamicParam.clear() }) Button("=").onClick({ e => dynamicParam.calculate() }) } } } ``` -------------------------------- ### Cangjie Entry Component and Basic UI Structure Source: https://context7.com/piagari/reference/llms.txt Defines the root UI component using @Entry and @Component decorators. The build() function declaratively describes the UI, and state changes (e.g., using @State) automatically trigger re-renders. This example shows a simple counter with a button. ```cangjie package ohos_app_cangjie_entry import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* import std.random.* @Entry @Component class EntryView { // State variables - changes trigger automatic UI updates @State var count: Int64 = 0 // Lifecycle hook - called before component renders public func aboutToAppear(): Unit { println("Component is about to appear") } // Build function defines the UI tree func build() { Column(20) { Text("Count: ${count}") .fontSize(32.px) .fontColor(0x333333) .fontWeight(FontWeight.Bold) Button("Increment") .shape(ShapeType.Normal) .borderRadius(8) .backgroundColor(0x0065ff) .fontColor(0xffffff) .onClick({ e: ClickEvent => count++ // State change triggers re-render }) } .width(100.percent) .padding(20) .alignItems(HorizontalAlign.Center) } } ``` -------------------------------- ### Animations with animateTo in Cangjie Source: https://context7.com/piagari/reference/llms.txt Illustrates creating smooth UI transitions using `animateTo` with customizable curves, durations, and callbacks. It shows animating text size and handling touch-based animations. Dependencies include `ohos.base`, `ohos.component`, `ohos.state_manage`, and `ohos.state_macro_manage`. ```cangjie package ohos_app_cangjie_entry import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* @Entry @Component class AnimationExample { @State var gameBegin: Bool = false @State var numbers: ObservedArray = ObservedArray([0, 0, 0, 0]) let animateTextSize = AnimateParam( duration: 100, curve: Curve.Linear ) // Animate state change func changeGame(): Unit { animateTo(AnimateParam(duration: 1000), { => this.gameBegin = !this.gameBegin }) } // Animate with callback func moveAnimate(animateCallBack: () -> Unit, onFinish: () -> Unit): Unit { animateTo( AnimateParam( duration: 200, curve: Curve.FastOutLinearIn, delay: 0, iterations: 1, playMode: PlayMode.Normal, onFinish: onFinish, expectedFrameRateRange: ExpectedFrameRateRange( min: 10, max: 60, expected: 30, ) ), animateCallBack ) } func build() { Column { // Animated text size Text("Score") .animationStart(animateTextSize) .fontSize(if (gameBegin) { 40 } else { 24 }) .animationEnd() Button(if (gameBegin) { "Stop" } else { "Start" }) .onClick { changeGame() } // Touch-based animation Grid { ForEach(numbers, itemGeneratorFunc: { num, idx => GridItem { Text("${num}") } }) } .onTouch { event => if ("Up" == event.eventType.toString()) { moveAnimate( { => /* update numbers */ }, { => /* spawn new tile */ } ) } } } } } ``` -------------------------------- ### SilkUI Button Component Usage Source: https://context7.com/piagari/reference/llms.txt Provides examples of using the SilkButton component from the SilkUI library in Cangjie. It covers various configurations including different types, sizes, states (loading, disabled), and custom styling with colors and icons. ```cangjie package silkui.components.button import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* // Button types: DEFAULT, PRIMARY, SUCCESS, WARNING, DANGER // Button sizes: LARGE, NORMAL, SMALL, MINI // Basic usage SilkButton(props: SilkButtonOptions(text: "Default Button")) // Primary button SilkButton(props: SilkButtonOptions( text: "Primary Button", buttonType: SilkButtonType.PRIMARY )) // Sized buttons SilkButton(props: SilkButtonOptions( text: "Large Button", size: SilkButtonSize.LARGE )) SilkButton(props: SilkButtonOptions( text: "Mini Button", size: SilkButtonSize.MINI )) // Plain (outlined) button SilkButton(props: SilkButtonOptions( text: "Plain Button", buttonType: SilkButtonType.PRIMARY, plain: true )) // Button with loading state @State var loading: Bool = false SilkButtonLoading( props: SilkButtonOptions( text: "Submit", buttonType: SilkButtonType.PRIMARY ), loading: loading, click: { e => loading = true // Perform async operation spawn { doAsyncWork() launch { loading = false } } } ) // Button with custom color and icon SilkButton(props: SilkButtonOptions( text: "Custom", color: Color(255, 0, 0, alpha: 1.0), icon: "search", iconPosition: SilkButtonIconPosition.LEFT )) // Disabled button SilkButtonDisabled( props: SilkButtonOptions(text: "Disabled"), disabled: true ) ``` -------------------------------- ### Call ArkTS APIs from Cangjie Source: https://context7.com/piagari/reference/llms.txt This snippet demonstrates calling ArkTS APIs from Cangjie. It initializes the JSRuntime, loads the 'calendarManager' system module, and retrieves the ability context. It then shows how to call a synchronous ArkTS method to get a calendar manager object. ```cangjie package ohos_app_cangjie_entry.services import ohos.ability.context.AbilityContext import ohos.ability.context.common.getStageContext import ohos.interop.js.* public class CalendarService { private static var abilityCtx: ?AbilityContext = None private static var runtime: JSRuntime = JSRuntime() // Keep runtime alive public static func initialize(abilityContext: AbilityContext): Unit { abilityCtx = abilityContext } public static func getCalendarManager(onResult: (JSObject) -> Unit) { let jsContext: JSContext = runtime.mainContext() // Load ArkTS system module let module: JSObject = jsContext.requireSystemNativeModule("calendarManager").asObject() // Get ArkTS context for the ability let tsContext: JSValue = jsContext.getAbilityContext(abilityCtx.getOrThrow()).toJSValue() // Call synchronous ArkTS method let callResult: JSValue = module.callMethod("getCalendarManager", tsContext) let manager: JSObject = callResult.asObject() onResult(manager) } public static func getEvents(calendar: JSObject, onResult: (ArrayList) -> Unit) { let ctx: JSContext = runtime.mainContext() // Call async ArkTS method returning Promise let getEventsPromise: JSPromise = calendar.callMethod("getEvents").asPromise() getEventsPromise.then( // Success callback ctx.function { innerCtx: JSContext, innerCallinfo: JSCallInfo => let jsEvents: JSArray = innerCallinfo[0].asArray() let events: ArrayList = ArrayList() // Parse ArkTS array to Cangjie objects for (i in 0..jsEvents.size) { let jsEvent: JSObject = jsEvents[i].asObject() let id: Int64 = Int64(jsEvent.getProperty("id").asNumber().toFloat64()) let title: String = jsEvent.getProperty("title").asString().toString() let startTime: Int64 = Int64(jsEvent.getProperty("startTime").asNumber().toFloat64()) events.append(EventInfo(id, title, startTime)) } onResult(events) innerCtx.undefined().toJSValue() }, // Error callback onRejected: ctx.function { innerCtx: JSContext, _: JSCallInfo => appLog.error("Failed to get events!") onResult(ArrayList()) innerCtx.undefined().toJSValue() } ) } public static func deleteEvent(calendar: JSObject, eventId: Int64) { let ctx: JSContext = runtime.mainContext() // Convert Cangjie value to JSValue let eventIdValue: JSValue = ctx.number(Float64(eventId)).toJSValue() // Call async delete method let deletePromise: JSPromise = calendar.callMethod("deleteEvent", eventIdValue).asPromise() deletePromise.then( ctx.function { innerCtx, _ => appLog.info("Event deleted successfully") innerCtx.undefined().toJSValue() }, onRejected: ctx.function { innerCtx, _ => appLog.error("Failed to delete event") innerCtx.undefined().toJSValue() } ) } } ``` -------------------------------- ### Execute MySQL Query with MysqlRecordApi Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/News/NewsServer/mysqlclient-ffi/doc/feature_api.md This example shows how to execute a MySQL query using the MysqlRecordApi. It initializes the MySQL driver, opens a data source, and establishes a connection. Then, it calls `mysqlQuery` with an empty string, which is expected to return an error code, and asserts this behavior. Finally, it closes the connection. ```Cangjie import mysqlclient_ffi.* import std.unittest.* import std.unittest.testmacro.* main():Int64{ // 初始化数据库驱动 let mysqlDriver: MysqlDriver = MysqlDriver("mysql") // 通过connectionString和选项打开数据源 let mysqlDatasource: MysqlDatasource = mysqlDriver.open( "HOST=127.0.0.1;USER=root;PASSWD=123;DB=mysql;PORT=3306;UNIX_SOCKET=;CLIENT_FLAG=0", Array<(String, String)>() ) // 返回一个可用的链接 let mysqlConnection: MysqlConnection = mysqlDatasource.connect() let mysqlRecordApi: MysqlRecordApi = MysqlRecordApi(mysqlConnection) let retInt32: Int32 = mysqlRecordApi.mysqlQuery("") @Assert(1, retInt32) // 关闭链接 mysqlConnection.close() } ``` -------------------------------- ### SilkUI Toast Notification Usage Source: https://context7.com/piagari/reference/llms.txt Illustrates how to use SilkToast for displaying temporary feedback messages in Cangjie applications. Examples include initializing the toast system, showing different types of toasts (success, error, warning, plain), configuring options, and managing loading toasts. ```cangjie package silkui.components.toast import ohos.base.* import ohos.component.* import silkui.components.toast.* // Initialize toast (call once in your app) SilkToast.silkToastInit(Option.None) // Success toast SilkToast.success("Operation completed successfully!") // Error toast SilkToast.error("Something went wrong") // Warning toast SilkToast.warn("Please check your input") // Plain toast SilkToast.toast("Message sent") // Toast with options SilkToast.success(SilkToastOptions( message: "File uploaded", duration: 5000, // 5 seconds showPosition: SilkToastPosition.TOP, // TOP, CENTER, BOTTOM showIcon: true, closeOnClick: true )) // Loading toast with controller let controller = SilkToast.loading(SilkToastOptions( message: "Processing...", duration: 0 // Won't auto-close )) // Update loading message controller.setMessage("Almost done...") // Close loading toast manually SilkToast.closeToast() // Allow multiple toasts simultaneously allowMultipleToast(Option.Some(true)) // Component-based toast for controlled visibility @State var showToast: Bool = false SilkToastComponent( show: showToast, props: SilkToastOptions( message: "Notification", duration: 3000 ) ) Button("Show Toast").onClick { showToast = true } ``` -------------------------------- ### Cangjie Ability and Window Stage Management Source: https://context7.com/piagari/reference/llms.txt Manages the application lifecycle and window creation using the MainAbility class, which extends Ability. It loads the entry view into the window stage upon creation. This snippet demonstrates basic ability lifecycle hooks and window loading. ```cangjie package ohos_app_cangjie_entry internal import ohos.base.AppLog internal import ohos.ability.AbilityStage internal import ohos.ability.LaunchReason import cj_res_entry.app class MainAbility <: Ability { public init() { super() registerSelf() } public override func onCreate(want: Want, launchParam: LaunchParam): Unit { AppLog.info("MainAbility OnCreated.${want.abilityName}") match (launchParam.launchReason) { case LaunchReason.START_ABILITY => AppLog.info("START_ABILITY") case _ => () } } public override func onWindowStageCreate(windowStage: WindowStage): Unit { AppLog.info("MainAbility onWindowStageCreate.") windowStage.loadContent("EntryView") // Load the entry component } } ``` -------------------------------- ### CMake Project Setup and Library Linking Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/AIClassify/entry/src/main/cpp/CMakeLists.txt This snippet configures the CMake build system for the native_demo project. It sets the minimum required CMake version, defines the project name, includes necessary directories, and links the 'entry' shared library with its dependencies. ```cmake cmake_minimum_required(VERSION 3.5.0) project(native_demo) # add_definitions(-DUSE_NNRT=1) set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) if(DEFINED PACKAGE_FIND_FILE) include(${PACKAGE_FIND_FILE}) endif() include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include) # set(CMAKE_C_STANDARD 11) add_library(entry SHARED ms_lite.c) target_link_libraries(entry PUBLIC mindspore_lite_ndk) target_link_libraries(entry PUBLIC hilog_ndk.z) # target_link_libraries(entry PUBLIC rawfile.z) # target_link_libraries(entry PUBLIC ace_napi.z) ``` -------------------------------- ### Extend Cangjie Types with Custom Methods Source: https://context7.com/piagari/reference/llms.txt Demonstrates how to use the `extend` keyword in Cangjie to add custom methods to existing types like Column, Button, and Image. These extensions facilitate cleaner, chainable API calls and reusable styling. ```cangjie package ohos_app_cangjie_entry import ohos.base.* import ohos.component.* import ohos.router.Router // Extend Column with custom styling methods extend Column { func card() { this.borderRadius(10) .justifyContent(FlexAlign.SpaceBetween) .alignItems(HorizontalAlign.Start) } func redirect(url: String) { this.onClick({ e: ClickEvent => Router.push(url: url) }) } } // Extend Button with common styles extend Button { func rounded() { this.shape(ShapeType.Normal) .borderRadius(6.fp) } func primary() { this.backgroundColor(0x0065ff) .fontColor(0xffffff) .fontSize(16) } func butStyle() { this.fontSize(25) .margin(top: 40) .height(50) .width(70.percent) .backgroundColor(0x00A09E5F) } } // Extend Image with size helper extend Image { public func size() { this.size(width: 30, height: 30) } } // Usage in component: @Component class StyledComponent { func build() { Column { Button("Primary Action") .rounded() .primary() .onClick { /* action */ } Image(@r(app.media.icon)).size() } .card() .redirect("DetailView") } } ``` -------------------------------- ### AppStorage: Global State Management in Cangjie Source: https://context7.com/piagari/reference/llms.txt Demonstrates how to use AppStorage to create and manage application-wide persistent state. AppStorage variables persist across application restarts. It is suitable for storing global settings like user preferences or high scores. ```cangjie package ohos_app_cangjie_entry import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* import std.collection.* // AppStorage - Application-wide state let storageHistory = AppStorage.setOrCreate("history", ObservedArrayList([])) let storageThemeIndex = AppStorage.setOrCreate("themeIndex", 0) let storageMaxScore = AppStorage.setOrCreate("maxScore", 0) @Entry @Component class AppStorageExample { // Bind to AppStorage @StorageLink["history"] var history: ObservedArrayList = ObservedArrayList([]) @StorageLink["themeIndex"] var themeIndex: Int64 = 0 @StorageLink["maxScore"] var maxScore: Int64 = 0 func build() { Column { Text("Max Score: ${maxScore}") Button("Update Score").onClick { if (currentScore > maxScore) { maxScore = currentScore // Persists across app restarts } } } } } ``` -------------------------------- ### Handle Asynchronous ArkTS Methods in Cangjie Source: https://context7.com/piagari/reference/llms.txt This snippet shows how to handle asynchronous ArkTS methods that return Promises from Cangjie. It demonstrates calling the 'getEvents' method, processing the resolved Promise with a success callback that parses ArkTS arrays into Cangjie objects, and includes an error callback for failed operations. ```cangjie public static func getEvents(calendar: JSObject, onResult: (ArrayList) -> Unit) { let ctx: JSContext = runtime.mainContext() // Call async ArkTS method returning Promise let getEventsPromise: JSPromise = calendar.callMethod("getEvents").asPromise() getEventsPromise.then( // Success callback ctx.function { innerCtx: JSContext, innerCallinfo: JSCallInfo => let jsEvents: JSArray = innerCallinfo[0].asArray() let events: ArrayList = ArrayList() // Parse ArkTS array to Cangjie objects for (i in 0..jsEvents.size) { let jsEvent: JSObject = jsEvents[i].asObject() let id: Int64 = Int64(jsEvent.getProperty("id").asNumber().toFloat64()) let title: String = jsEvent.getProperty("title").asString().toString() let startTime: Int64 = Int64(jsEvent.getProperty("startTime").asNumber().toFloat64()) events.append(EventInfo(id, title, startTime)) } onResult(events) innerCtx.undefined().toJSValue() }, // Error callback onRejected: ctx.function { innerCtx: JSContext, _: JSCallInfo => appLog.error("Failed to get events!") onResult(ArrayList()) innerCtx.undefined().toJSValue() } ) } ``` -------------------------------- ### LocalStorage: Component Tree State Sharing in Cangjie Source: https://context7.com/piagari/reference/llms.txt Illustrates how to use LocalStorage for sharing state within a component tree. LocalStorage is ideal for managing state that needs to be accessed by multiple sibling or child components without prop drilling. It requires attaching the LocalStorage instance to the entry component. ```cangjie // LocalStorage - Component tree state sharing let storage = LocalStorage() @Observed public class SeatSelection { @Publish public var selectedSeats: ObservedArrayList = ObservedArrayList() } @Entry[storage] // Attach LocalStorage to entry @Component class ParentComponent { func build() { Column { SeatGrid() // Child can access shared state SeatSummary() // Sibling can also access } } } @Component class SeatGrid { @LocalStorageLink['viewModel'] var viewModel: SeatSelection = SeatSelection() func build() { Grid { ForEach(seats, itemGeneratorFunc: { seat, idx => GridItem { Text(seat.name) .onClick { viewModel.selectedSeats.append(seat) } } }) } } } @Component class SeatSummary { @LocalStorageLink['viewModel'] var viewModel: SeatSelection = SeatSelection() func build() { Column { Text("Selected: ${viewModel.selectedSeats.size} seats") ForEach(viewModel.selectedSeats, { seat, _ => Text(seat.name) }) } } } ``` -------------------------------- ### Delete Event using Asynchronous ArkTS Method in Cangjie Source: https://context7.com/piagari/reference/llms.txt This snippet illustrates how to call an asynchronous ArkTS method ('deleteEvent') from Cangjie that returns a Promise. It shows the conversion of a Cangjie Int64 value to a JSValue and handles the Promise resolution with success and error callbacks for logging the operation status. ```cangjie public static func deleteEvent(calendar: JSObject, eventId: Int64) { let ctx: JSContext = runtime.mainContext() // Convert Cangjie value to JSValue let eventIdValue: JSValue = ctx.number(Float64(eventId)).toJSValue() // Call async delete method let deletePromise: JSPromise = calendar.callMethod("deleteEvent", eventIdValue).asPromise() deletePromise.then( ctx.function { innerCtx, _ => appLog.info("Event deleted successfully") innerCtx.undefined().toJSValue() }, onRejected: ctx.function { innerCtx, _ => appLog.error("Failed to delete event") innerCtx.undefined().toJSValue() } ) } ``` -------------------------------- ### LLM Chat Integration with HTTP Client in Cangjie Source: https://context7.com/piagari/reference/llms.txt This Cangjie code implements an LLM client that integrates with an HTTP client to send requests to an LLM API. It supports both streaming and non-streaming chat responses, with an option to maintain chat history. Dependencies include standard libraries for I/O, time, JSON encoding, HTTP, and TLS. ```cangjie package ohos_app_cangjie_entry.utils import std.io.StringReader import std.time.Duration import encoding.json.* import net.http.* import net.tls.* public enum Role <: ToString { I | AI | System public func toString() { match (this) { case I => 'user' case AI => 'assistant' case System => 'system' } } } public class LLM { let client: Client let history = StringBuilder() public LLM(let url!: String, let key!: String, let model!: String, let memory!: Bool = false) { var config = TlsClientConfig() config.verifyMode = TrustAll client = ClientBuilder() .tlsConfig(config) .readTimeout(Duration.Max) .build() } func encode(role: Role, content: String) { '{"role":"${role}","content":${JsonString(content)}}"' } func send(input: String, stream!: Bool = false) { let message = encode(I, input) let content = '{"model":"${model}","messages":[${history}${message}],"stream":${stream}}' if (memory) { history.append(message) } let request = HttpRequestBuilder() .url(url) .header('Authorization', 'Bearer ${key}') .header('Content-Type', 'application/json') .header('Accept', if (stream) { 'text/event-stream' } else { 'application/json' }) .body(content) .post() .build() client.send(request) } // Streaming chat with callback for each token public func chats(input: String, task: (String) -> Unit) { const INDEX = 6 let response = send(input, stream: true) let output = StringBuilder() let buffer = Array(1024 * 8, item: 0) var length = response.body.read(buffer) while (length != 0) { let text = String.fromUtf8(buffer[..length]) for (line in text.split('\n', removeEmpty: true)) { if (line.size > INDEX && line[INDEX] == b'{') { let json = line[INDEX..line.size] let slice = parse(json, stream: true) if (memory) { output.append(slice) } task(slice) // Callback with each token } } length = response.body.read(buffer) } if (memory) { history.append(',${encode(AI, output.toString())},') } } // Non-streaming chat public func chat(input: String) { let response = send(input) let output = StringReader(response.body).readToEnd() |> parse if (memory) { history.append(',${encode(AI, output)},') } return output } public func reset() { history.reset() } } // Usage: let llm = LLM( url: 'https://api.siliconflow.cn/v1/chat/completions', key: 'sk-your-api-key', model: 'deepseek-ai/DeepSeek-V3', memory: true ) // Streaming response llm.chats("Hello!") { slice: String => launch { output += slice } // Update UI on main thread } ``` -------------------------------- ### Initialize and Manage MySQL Server with MysqlServerApi Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/News/NewsServer/mysqlclient-ffi/doc/feature_api.md This code snippet demonstrates initializing and managing a MySQL server instance using MysqlServerApi. It sets up the MySQL driver and connection, then initializes the server with provided arguments. It also shows how to perform server refresh and kill operations, and finally shuts down the server instance and closes the connection. ```Cangjie import mysqlclient_ffi.* import std.unittest.* import std.unittest.testmacro.* main():Int64{ // 初始化数据库驱动 let mysqlDriver: MysqlDriver = MysqlDriver("mysql") // 通过connectionString和选项打开数据源 let mysqlDatasource: MysqlDatasource = mysqlDriver.open( "HOST=127.0.0.1;USER=root;PASSWD=123;DB=mysql;PORT=3306;UNIX_SOCKET=;CLIENT_FLAG=0", Array<(String, String)>() ) // 返回一个可用的链接 let mysqlConnection: MysqlConnection = mysqlDatasource.connect() let mysqlServerApi: MysqlServerApi = MysqlServerApi(mysqlConnection) var cpCtringArgv: CPointer = CPointer() var cpCtringGroups: CPointer = CPointer() var ret: Int32 = mysqlServerApi.mysqlServerInit(10, cpCtringArgv, cpCtringGroups) @Assert(0, ret) mysqlServerApi.mysqlServerEnd() ret = mysqlServerApi.mysqlRefresh(0) @Assert(0, ret) ret = mysqlServerApi.mysqlKill(0) @Assert(1, ret) mysqlConnection.close() } ``` -------------------------------- ### List MySQL Databases with MysqlListApi Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/News/NewsServer/mysqlclient-ffi/doc/feature_api.md This snippet demonstrates how to list databases in MySQL using the MysqlListApi. It initializes the MySQL driver, opens a data source, establishes a connection, and then uses MysqlListApi to fetch database information. It also verifies the number of fields, EOF status, and rows returned, and iterates through the fetched rows. ```Cangjie import mysqlclient_ffi.* import std.unittest.* import std.unittest.testmacro.* main():Int64{ // 初始化数据库驱动 let mysqlDriver: MysqlDriver = MysqlDriver("mysql") // 通过connectionString和选项打开数据源 let mysqlDatasource: MysqlDatasource = mysqlDriver.open( "HOST=127.0.0.1;USER=root;PASSWD=123;DB=mysql;PORT=3306;UNIX_SOCKET=;CLIENT_FLAG=0", Array<(String, String)>() ) // 返回一个可用的链接 let mysqlConnection: MysqlConnection = mysqlDatasource.connect() let mysqlListApi: MysqlListApi = MysqlListApi(mysqlConnection) let mysqlRecordApi: MysqlRecordApi = MysqlRecordApi(mysqlConnection) let cp1: CPointer = mysqlListApi.mysqlListDbs("information_schema") let retFields: UInt32 = mysqlRecordApi.mysqlNumFields(cp1) @Assert(1, retFields) let retEof: Bool = mysqlRecordApi.mysqlEof(cp1) @Assert(true, retEof) let retRows: UInt64 = mysqlRecordApi.mysqlNumRows(cp1) @Assert(1, retRows) unsafe { for (i in 0..retRows) { var cpCString: CPointer = mysqlRecordApi.mysqlFetchRow(cp1) for (j in 0..retFields) { var cString: CString = cpCString.read(Int64(j)) if (i == 0) { @Assert("information_schema", cString.toString()) } } } } mysqlRecordApi.mysqlFreeResult(cp1) mysqlConnection.close() } ``` -------------------------------- ### CoverCard Component Definition (ArkTS) Source: https://github.com/piagari/reference/blob/main/HarmonyOS-Examples-main/HarmonyOS-Examples-main/WaterFall/entry/src/main/cangjie/src/component/card/CoverCard.txt Defines the CoverCard component, including its properties (mediaType, title, desc), state variables (onPlaying), and event handling for touch interactions. It uses ArkTS syntax for UI declaration and logic. ```arkts /** * Created on 2024/8/26 */ package ohos_app_cangjie_entry.component.card import ohos.base.* import ohos.component.* import ohos.state_manage.* import ohos.state_macro_manage.* import std.sync.{Timer, sleep} import std.time.{Duration} import ohos_app_cangjie_entry.entity.* import ohos_app_cangjie_entry.mock.VideoData let TOP_BORDER_RADIUS = 6.fp @Component public class CoverCard { // 资源类型 @Prop var mediaType: MediaType // 标题 @Prop var title: String // 文本描述 @Prop var desc: String @State var onPlaying: Bool = false let videoController = func cardOnTouch(e: TouchEvent) { if (let MediaType.VIDEO(_) <- this.mediaType) { if (let TouchType.Up <- e.eventType) { this.stopVideo() } else if(let TouchType.Down <- e.eventType) { this.playVideo() } } } func playVideo() { this.onPlaying = true this.videoController.start() } func stopVideo() { this.onPlaying = false this.videoController.stop() } func build() { Column(10) { if(let IMAGE(src) <- mediaType) { Image(src).width(100.percent) .borderRadius(topLeft: TOP_BORDER_RADIUS, topRight: TOP_BORDER_RADIUS) .objectFit(ImageFit.Cover) } else if (let VIDEO(src) <- mediaType) { if (this.onPlaying) { Video(src: src[1], controller: videoController) .objectFit(ImageFit.Fill).height(150) .loop(true) .controls(false) } else { Image(src[0]).width(100.percent) .borderRadius(topLeft: TOP_BORDER_RADIUS, topRight: TOP_BORDER_RADIUS) .objectFit(ImageFit.Fill).height(150) } } Column(10) { Text(title).fontSize(14).width(100.percent) Text(desc).fontSize(12).width(100.percent) }.padding(left: 10, right: 10, bottom: 10) }.width(100.percent) .alignItems(HorizontalAlign.Start) .borderRadius(TOP_BORDER_RADIUS) .backgroundColor(0xffffff) .onTouch(cardOnTouch) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.