mirror of https://github.com/anoshenko/rui.git
Added ClientSession interface
* Added ClientSession interface * Added ClientSession method to Session interface * Removed ClientItem, SetClientItem, RemoveClientItem, and RemoveAllClientItems methods from Session interface
This commit is contained in:
parent
7b442dea72
commit
85e244babf
|
|
@ -3,7 +3,9 @@
|
|||
* Removed "style-disabled" property and GetDisabledStyle function
|
||||
* Added GoogleFonts field to AppParams
|
||||
* Added functions: GetWhiteSpace, GetWordBreak, ScrollIntoViewIfNeeded
|
||||
* Added Popups, PopupDefault, PopupDefaultsSeq, and SetPopupDefaults methods to Session interface
|
||||
* Added ClientSession interface
|
||||
* Added ClientSession, Popups, PopupDefault, PopupDefaultsSeq, and SetPopupDefaults methods to Session interface
|
||||
* Removed ClientItem, SetClientItem, RemoveClientItem, and RemoveAllClientItems methods from Session interface
|
||||
* Added DismissWithoutAnimation add SetHotKey methods to Popup interface
|
||||
* Added "outside-color" add "outside-filter" properties to Popup interface
|
||||
* Added ViewSeq add ViewCount methods to ParentView interface
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ function sessionInfo() {
|
|||
message += ",pixel-ratio=" + pixelRatio;
|
||||
}
|
||||
|
||||
/*
|
||||
if (localStorage.length > 0) {
|
||||
message += ",storage="
|
||||
lead = "_{"
|
||||
|
|
@ -73,6 +74,7 @@ function sessionInfo() {
|
|||
}
|
||||
message += "}"
|
||||
}
|
||||
*/
|
||||
|
||||
return message + "}";
|
||||
}
|
||||
|
|
@ -1984,6 +1986,38 @@ function getCanvasContext(elementId) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function localStorageGet(request, keys) {
|
||||
const key_set = keys.split(",");
|
||||
var result = "";
|
||||
for (const key of key_set) {
|
||||
result += key;
|
||||
result += ":";
|
||||
try {
|
||||
let value = localStorage.getItem(key);
|
||||
if (value) {
|
||||
result += value;
|
||||
}
|
||||
} catch (err) {}
|
||||
result += ";";
|
||||
}
|
||||
sendMessage("storageValues{session=" + sessionID + ", request=" + request + ", values=`" + result + "`}")
|
||||
}
|
||||
|
||||
function localStorageGetAll(request) {
|
||||
var result = "";
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
let key = localStorage.key(i);
|
||||
let value = localStorage.getItem(key);
|
||||
if (value) {
|
||||
result += key;
|
||||
result += ":";
|
||||
result += value;
|
||||
result += ";";
|
||||
}
|
||||
}
|
||||
sendMessage("storageValues{session=" + sessionID + ", request=" + request + ", values=`" + result + "`}")
|
||||
}
|
||||
|
||||
function localStorageSet(key, value) {
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ClientStorage is an interface for accessing client-side key-value storage.
|
||||
type ClientStorage interface {
|
||||
|
||||
// Request performs an asynchronous request to obtain key-value pairs from client-side storage.
|
||||
//
|
||||
// The first argument specifies the function that is called for each key-value pair
|
||||
// (if the pair is not in storage, then the function is called with an empty string as its value).
|
||||
//
|
||||
// The second argument specifies the set of keys to request.
|
||||
// If no key is specified, then a query is performed for all possible key-value pairs.
|
||||
Request(result func(key, value string), key ...string)
|
||||
|
||||
// Get returns a value by key from the client-side storage.
|
||||
//
|
||||
// If the key-value pair is not in the client-side storage, then the function returns an empty string.
|
||||
Get(key string) string
|
||||
|
||||
// Set stores a key-value pair in the client-side storage.
|
||||
//
|
||||
// An empty string as a value removes the key-value pair.
|
||||
Set(key, value string)
|
||||
|
||||
// RemoveAll removes all key-value pair from the client-side storage
|
||||
RemoveAll()
|
||||
|
||||
handleEvent(command string, data DataObject)
|
||||
}
|
||||
|
||||
type clientStorageData struct {
|
||||
bridge bridge
|
||||
getResult map[int]func(string, string)
|
||||
lastRequest int
|
||||
}
|
||||
|
||||
func (session *sessionData) ClientStorage() ClientStorage {
|
||||
if session.clientStorage == nil {
|
||||
storage := new(clientStorageData)
|
||||
storage.bridge = session.bridge
|
||||
session.clientStorage = storage
|
||||
}
|
||||
return session.clientStorage
|
||||
}
|
||||
|
||||
func encodeClientStorageText(text string) string {
|
||||
return base64.URLEncoding.EncodeToString([]byte(text))
|
||||
}
|
||||
|
||||
func decodeClientStorageText(text string) string {
|
||||
result, _ := base64.URLEncoding.DecodeString(text)
|
||||
return string(result)
|
||||
}
|
||||
|
||||
func (storage *clientStorageData) Get(key string) string {
|
||||
result := make(chan string)
|
||||
defer close(result)
|
||||
|
||||
storage.Request(func(key, value string) {
|
||||
result <- value
|
||||
}, key)
|
||||
|
||||
return <-result
|
||||
}
|
||||
|
||||
func (storage *clientStorageData) Request(result func(key, value string), key ...string) {
|
||||
if result == nil {
|
||||
return
|
||||
}
|
||||
|
||||
storage.lastRequest++
|
||||
request := storage.lastRequest
|
||||
storage.getResult[request] = result
|
||||
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
for _, k := range key {
|
||||
if k != "" {
|
||||
if buffer.Len() > 0 {
|
||||
buffer.WriteRune(',')
|
||||
}
|
||||
buffer.WriteString(encodeClientStorageText(k))
|
||||
}
|
||||
}
|
||||
|
||||
if buffer.Len() == 0 {
|
||||
storage.bridge.callFunc("localStorageGetAll", request)
|
||||
} else {
|
||||
storage.bridge.callFunc("localStorageGet", request, buffer.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (storage *clientStorageData) Set(key, value string) {
|
||||
key = encodeClientStorageText(key)
|
||||
if value != "" {
|
||||
storage.bridge.callFunc("localStorageSet", key, encodeClientStorageText(value))
|
||||
} else {
|
||||
storage.bridge.callFunc("localStorageRemove", key)
|
||||
}
|
||||
}
|
||||
|
||||
func (storage *clientStorageData) RemoveAll() {
|
||||
storage.bridge.callFunc("localStorageClear")
|
||||
}
|
||||
|
||||
func (storage *clientStorageData) handleEvent(command string, data DataObject) {
|
||||
request := 0
|
||||
if text, ok := data.PropertyValue("request"); ok {
|
||||
var err error
|
||||
if request, err = strconv.Atoi(text); err != nil {
|
||||
ErrorLog(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ErrorLog("'request' property not found (command: " + command + ")")
|
||||
return
|
||||
}
|
||||
|
||||
switch command {
|
||||
case "storageError":
|
||||
if text, ok := data.PropertyValue("error"); ok {
|
||||
ErrorLog(text)
|
||||
}
|
||||
|
||||
//case "storageSuccess":
|
||||
|
||||
case "storageValues":
|
||||
fn, ok := storage.getResult[request]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
delete(storage.getResult, request)
|
||||
|
||||
text, ok := data.PropertyValue("error")
|
||||
if !ok {
|
||||
ErrorLog("'values' property not found (command: storageValues)")
|
||||
return
|
||||
}
|
||||
|
||||
for pair := range strings.SplitSeq(text, ";") {
|
||||
if data := strings.Split(pair, ":"); len(data) == 2 {
|
||||
key := decodeClientStorageText(data[0])
|
||||
value := decodeClientStorageText(data[1])
|
||||
fn(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
52
session.go
52
session.go
|
|
@ -135,17 +135,8 @@ type Session interface {
|
|||
// OpenURL opens the url in the new browser tab
|
||||
OpenURL(url string)
|
||||
|
||||
// ClientItem reads value by key from the client-side storage
|
||||
ClientItem(key string) (string, bool)
|
||||
|
||||
// SetClientItem stores a key-value pair in the client-side storage
|
||||
SetClientItem(key, value string)
|
||||
|
||||
// RemoveClientItem removes a key-value pair in the client-side storage
|
||||
RemoveClientItem(key string)
|
||||
|
||||
// RemoveAllClientItems removes all key-value pair from the client-side storage
|
||||
RemoveAllClientItems()
|
||||
// ClientStorage returns an interface for accessing client-side key-value storage.
|
||||
ClientStorage() ClientStorage
|
||||
|
||||
// SetHotKey sets the function that will be called when the given hotkey is pressed.
|
||||
// Invoke SetHotKey(..., ..., nil) for remove hotkey function.
|
||||
|
|
@ -248,12 +239,12 @@ type sessionData struct {
|
|||
animationCounter int
|
||||
animationCSS string
|
||||
updateScripts map[string]*strings.Builder
|
||||
clientStorage map[string]string
|
||||
hotkeys map[string]func(Session)
|
||||
timers map[int]func(Session)
|
||||
nextTimerID int
|
||||
pauseTime int64
|
||||
popupDefaults Params
|
||||
clientStorage ClientStorage
|
||||
}
|
||||
|
||||
func newSession(app Application, id int, customTheme string, params DataObject) Session {
|
||||
|
|
@ -270,7 +261,6 @@ func newSession(app Application, id int, customTheme string, params DataObject)
|
|||
session.animationCounter = 0
|
||||
session.animationCSS = ""
|
||||
session.updateScripts = map[string]*strings.Builder{}
|
||||
session.clientStorage = map[string]string{}
|
||||
session.hotkeys = map[string]func(Session){}
|
||||
session.timers = map[int]func(Session){}
|
||||
session.nextTimerID = 1
|
||||
|
|
@ -781,16 +771,6 @@ func (session *sessionData) handleSessionInfo(params DataObject) {
|
|||
session.pixelRatio = f
|
||||
}
|
||||
}
|
||||
|
||||
if node := params.PropertyByTag("storage"); node != nil && node.Type() == ObjectNode {
|
||||
if obj := node.Object(); obj != nil {
|
||||
for element := range obj.Properties() {
|
||||
if element.Type() == TextNode {
|
||||
session.clientStorage[element.Tag()] = element.Text()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) handleEvent(command string, data DataObject) {
|
||||
|
|
@ -826,9 +806,9 @@ func (session *sessionData) handleEvent(command string, data DataObject) {
|
|||
case "sessionInfo":
|
||||
session.handleSessionInfo(data)
|
||||
|
||||
case "storageError":
|
||||
if text, ok := data.PropertyValue("error"); ok {
|
||||
ErrorLog(text)
|
||||
case "storageError", "storageSuccess", "storageValues":
|
||||
if session.clientStorage != nil {
|
||||
session.clientStorage.handleEvent(command, data)
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
@ -932,26 +912,6 @@ func (session *sessionData) OpenURL(urlStr string) {
|
|||
session.callFunc("openURL", urlStr)
|
||||
}
|
||||
|
||||
func (session *sessionData) ClientItem(key string) (string, bool) {
|
||||
value, ok := session.clientStorage[key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
func (session *sessionData) SetClientItem(key, value string) {
|
||||
session.clientStorage[key] = value
|
||||
session.bridge.callFunc("localStorageSet", key, value)
|
||||
}
|
||||
|
||||
func (session *sessionData) RemoveClientItem(key string) {
|
||||
delete(session.clientStorage, key)
|
||||
session.bridge.callFunc("localStorageRemove", key)
|
||||
}
|
||||
|
||||
func (session *sessionData) RemoveAllClientItems() {
|
||||
session.clientStorage = map[string]string{}
|
||||
session.bridge.callFunc("localStorageClear")
|
||||
}
|
||||
|
||||
func (session *sessionData) addToEventsQueue(data DataObject) {
|
||||
session.events <- data
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue