diff --git a/README_ru.md b/README_ru.md
index fb393ac..3dcd9b7 100644
--- a/README_ru.md
+++ b/README_ru.md
@@ -15,7 +15,7 @@
* `ui:show_toast(string)` - показывает информационное сообщение в стиле Android;
* `ui:show_dialog(string, string, [string], [string])` - показать диалог; первый аргумент - заголовок, второй - текст, третий (опциональный) - имя первой кнопки, четвертый (опциональный) - имя второй кнопки;
* `ui:show_edit_dialog(string, [string], [string])` - показать диалог с полем ввода: 1 - заголовок, 2 - подпись, 3 - стандартное значения поля ввода;
-* `ui:show_checkbox_dialog(string, table, [string])` - показать дилога с выбром: 1 - заголовок, 2 - таблица строк, 3 - дефолтовое значение;
+* `ui:show_checkbox_dialog(string, table, [number])` - показать диалог с выбором: 1 - заголовок, 2 - таблица строк, 3 - индекс дефолтового значения;
* `ui:get_default_title()` - возвращает стандартный заголовок виджета (задается в метаданных `name`);
* `ui:set_title()` - изменяет заголовок виджета, функцию следует вызывать до функции отображения данных (пустая строка - сброс до стандартного заголовка);
* `ui:get_primary_text_color()` - возвращает цвет текста темы в формате #XXXXXX;
@@ -111,6 +111,7 @@ end
* `string:имя`
* `int:имя`
* `double:имя`
+* `boolean:имя`
Также вместо `object` можно использовать `array` если в JSON находится массив.
diff --git a/bad-script.lua b/bad-script.lua
index e7aae6a..85cde84 100644
--- a/bad-script.lua
+++ b/bad-script.lua
@@ -1,5 +1,9 @@
function on_resume()
+ ui:show_text("Click to freeze launcher")
+end
+
+function on_click()
while true do
- system:get_from_clipboard()
+ system:copy_to_clipboard("http://google.com")
end
end
diff --git a/bad-script2.lua b/bad-script2.lua
index 102216e..e38da0e 100644
--- a/bad-script2.lua
+++ b/bad-script2.lua
@@ -1,2 +1,5 @@
-ui:show_toast("Hello")
-
+function on_resume()
+ while true do
+ ui:show_text("Haha")
+ end
+end
diff --git a/bad-script3.lua b/bad-script3.lua
new file mode 100644
index 0000000..102216e
--- /dev/null
+++ b/bad-script3.lua
@@ -0,0 +1,2 @@
+ui:show_toast("Hello")
+
diff --git a/btc-widget.lua b/btc-widget.lua
index 6cfcc98..009ecb4 100644
--- a/btc-widget.lua
+++ b/btc-widget.lua
@@ -12,5 +12,5 @@ end
function on_network_result(result)
local price = ajson:get_value(result, "object object:USD string:last")
- ui:show_text("BTC"..equals..price.." USD")
+ ui:show_text("1 BTC"..equals..price.." USD")
end
diff --git a/checkbox-dialog-sample.lua b/checkbox-dialog-sample.lua
index 645c884..c800cfd 100644
--- a/checkbox-dialog-sample.lua
+++ b/checkbox-dialog-sample.lua
@@ -4,7 +4,7 @@ end
function on_click()
dialog_items = { "One", "Two", "Three" }
- ui:show_checkbox_dialog("Title", dialog_items, "Two")
+ ui:show_checkbox_dialog("Title", dialog_items, 2)
end
function on_dialog_action(idx)
diff --git a/lib/md_colors.lua b/lib/md_colors.lua
new file mode 100644
index 0000000..44a59f0
--- /dev/null
+++ b/lib/md_colors.lua
@@ -0,0 +1,295 @@
+md_colors = {
+ -- reds
+ red_50="#FFEBEE",
+ red_100="#FFCDD2",
+ red_200="#EF9A9A",
+ red_300="#E57373",
+ red_400="#EF5350",
+ red_500="#F44336",
+ red_600="#E53935",
+ red_700="#D32F2F",
+ red_800="#C62828",
+ red_900="#B71C1C",
+ red_A100="#FF8A80",
+ red_A200="#FF5252",
+ red_A400="#FF1744",
+ red_A700="#D50000",
+
+ -- pinks
+ pink_50="#FCE4EC",
+ pink_100="#F8BBD0",
+ pink_200="#F48FB1",
+ pink_300="#F06292",
+ pink_400="#EC407A",
+ pink_500="#E91E63",
+ pink_600="#D81B60",
+ pink_700="#C2185B",
+ pink_800="#AD1457",
+ pink_900="#880E4F",
+ pink_A100="#FF80AB",
+ pink_A200="#FF4081",
+ pink_A400="#F50057",
+ pink_A700="#C51162",
+
+ -- purples
+ purple_50="#F3E5F5",
+ purple_100="#E1BEE7",
+ purple_200="#CE93D8",
+ purple_300="#BA68C8",
+ purple_400="#AB47BC",
+ purple_500="#9C27B0",
+ purple_600="#8E24AA",
+ purple_700="#7B1FA2",
+ purple_800="#6A1B9A",
+ purple_900="#4A148C",
+ purple_A100="#EA80FC",
+ purple_A200="#E040FB",
+ purple_A400="#D500F9",
+ purple_A700="#AA00FF",
+
+ -- deep purples
+ deep_purple_50="#EDE7F6",
+ deep_purple_100="#D1C4E9",
+ deep_purple_200="#B39DDB",
+ deep_purple_300="#9575CD",
+ deep_purple_400="#7E57C2",
+ deep_purple_500="#673AB7",
+ deep_purple_600="#5E35B1",
+ deep_purple_700="#512DA8",
+ deep_purple_800="#4527A0",
+ deep_purple_900="#311B92",
+ deep_purple_A100="#B388FF",
+ deep_purple_A200="#7C4DFF",
+ deep_purple_A400="#651FFF",
+ deep_purple_A700="#6200EA",
+
+ -- indigo
+ indigo_50="#E8EAF6",
+ indigo_100="#C5CAE9",
+ indigo_200="#9FA8DA",
+ indigo_300="#7986CB",
+ indigo_400="#5C6BC0",
+ indigo_500="#3F51B5",
+ indigo_600="#3949AB",
+ indigo_700="#303F9F",
+ indigo_800="#283593",
+ indigo_900="#1A237E",
+ indigo_A100="#8C9EFF",
+ indigo_A200="#536DFE",
+ indigo_A400="#3D5AFE",
+ indigo_A700="#304FFE",
+
+ -- blue
+ blue_50="#E3F2FD",
+ blue_100="#BBDEFB",
+ blue_200="#90CAF9",
+ blue_300="#64B5F6",
+ blue_400="#42A5F5",
+ blue_500="#2196F3",
+ blue_600="#1E88E5",
+ blue_700="#1976D2",
+ blue_800="#1565C0",
+ blue_900="#0D47A1",
+ blue_A100="#82B1FF",
+ blue_A200="#448AFF",
+ blue_A400="#2979FF",
+ blue_A700="#2962FF",
+
+ -- light blue
+ light_blue_50="#E1F5FE",
+ light_blue_100="#B3E5FC",
+ light_blue_200="#81D4fA",
+ light_blue_300="#4fC3F7",
+ light_blue_400="#29B6FC",
+ light_blue_500="#03A9F4",
+ light_blue_600="#039BE5",
+ light_blue_700="#0288D1",
+ light_blue_800="#0277BD",
+ light_blue_900="#01579B",
+ light_blue_A100="#80D8FF",
+ light_blue_A200="#40C4FF",
+ light_blue_A400="#00B0FF",
+ light_blue_A700="#0091EA",
+
+ -- cyan
+ cyan_50="#E0F7FA",
+ cyan_100="#B2EBF2",
+ cyan_200="#80DEEA",
+ cyan_300="#4DD0E1",
+ cyan_400="#26C6DA",
+ cyan_500="#00BCD4",
+ cyan_600="#00ACC1",
+ cyan_700="#0097A7",
+ cyan_800="#00838F",
+ cyan_900="#006064",
+ cyan_A100="#84FFFF",
+ cyan_A200="#18FFFF",
+ cyan_A400="#00E5FF",
+ cyan_A700="#00B8D4",
+
+ -- teal
+ teal_50="#E0F2F1",
+ teal_100="#B2DFDB",
+ teal_200="#80CBC4",
+ teal_300="#4DB6AC",
+ teal_400="#26A69A",
+ teal_500="#009688",
+ teal_600="#00897B",
+ teal_700="#00796B",
+ teal_800="#00695C",
+ teal_900="#004D40",
+ teal_A100="#A7FFEB",
+ teal_A200="#64FFDA",
+ teal_A400="#1DE9B6",
+ teal_A700="#00BFA5",
+
+ -- green
+ green_50="#E8F5E9",
+ green_100="#C8E6C9",
+ green_200="#A5D6A7",
+ green_300="#81C784",
+ green_400="#66BB6A",
+ green_500="#4CAF50",
+ green_600="#43A047",
+ green_700="#388E3C",
+ green_800="#2E7D32",
+ green_900="#1B5E20",
+ green_A100="#B9F6CA",
+ green_A200="#69F0AE",
+ green_A400="#00E676",
+ green_A700="#00C853",
+
+ --light green
+ light_green_50="#F1F8E9",
+ light_green_100="#DCEDC8",
+ light_green_200="#C5E1A5",
+ light_green_300="#AED581",
+ light_green_400="#9CCC65",
+ light_green_500="#8BC34A",
+ light_green_600="#7CB342",
+ light_green_700="#689F38",
+ light_green_800="#558B2F",
+ light_green_900="#33691E",
+ light_green_A100="#CCFF90",
+ light_green_A200="#B2FF59",
+ light_green_A400="#76FF03",
+ light_green_A700="#64DD17",
+
+ -- lime
+ lime_50="#F9FBE7",
+ lime_100="#F0F4C3",
+ lime_200="#E6EE9C",
+ lime_300="#DCE775",
+ lime_400="#D4E157",
+ lime_500="#CDDC39",
+ lime_600="#C0CA33",
+ lime_700="#A4B42B",
+ lime_800="#9E9D24",
+ lime_900="#827717",
+ lime_A100="#F4FF81",
+ lime_A200="#EEFF41",
+ lime_A400="#C6FF00",
+ lime_A700="#AEEA00",
+
+ --yellow
+ yellow_50="#FFFDE7",
+ yellow_100="#FFF9C4",
+ yellow_200="#FFF590",
+ yellow_300="#FFF176",
+ yellow_400="#FFEE58",
+ yellow_500="#FFEB3B",
+ yellow_600="#FDD835",
+ yellow_700="#FBC02D",
+ yellow_800="#F9A825",
+ yellow_900="#F57F17",
+ yellow_A100="#FFFF82",
+ yellow_A200="#FFFF00",
+ yellow_A400="#FFEA00",
+ yellow_A700="#FFD600",
+
+ --amber
+ amber_50="#FFF8E1",
+ amber_100="#FFECB3",
+ amber_200="#FFE082",
+ amber_300="#FFD54F",
+ amber_400="#FFCA28",
+ amber_500="#FFC107",
+ amber_600="#FFB300",
+ amber_700="#FFA000",
+ amber_800="#FF8F00",
+ amber_900="#FF6F00",
+ amber_A100="#FFE57F",
+ amber_A200="#FFD740",
+ amber_A400="#FFC400",
+ amber_A700="#FFAB00",
+
+ --orange
+ orange_50="#FFF3E0",
+ orange_100="#FFE0B2",
+ orange_200="#FFCC80",
+ orange_300="#FFB74D",
+ orange_400="#FFA726",
+ orange_500="#FF9800",
+ orange_600="#FB8C00",
+ orange_700="#F57C00",
+ orange_800="#EF6C00",
+ orange_900="#E65100",
+ orange_A100="#FFD180",
+ orange_A200="#FFAB40",
+ orange_A400="#FF9100",
+ orange_A700="#FF6D00",
+
+ --deep orange
+ deep_orange_50="#FBE9A7",
+ deep_orange_100="#FFCCBC",
+ deep_orange_200="#FFAB91",
+ deep_orange_300="#FF8A65",
+ deep_orange_400="#FF7043",
+ deep_orange_500="#FF5722",
+ deep_orange_600="#F4511E",
+ deep_orange_700="#E64A19",
+ deep_orange_800="#D84315",
+ deep_orange_900="#BF360C",
+ deep_orange_A100="#FF9E80",
+ deep_orange_A200="#FF6E40",
+ deep_orange_A400="#FF3D00",
+ deep_orange_A700="#DD2600",
+
+ --brown
+ brown_50="#EFEBE9",
+ brown_100="#D7CCC8",
+ brown_200="#BCAAA4",
+ brown_300="#A1887F",
+ brown_400="#8D6E63",
+ brown_500="#795548",
+ brown_600="#6D4C41",
+ brown_700="#5D4037",
+ brown_800="#4E342E",
+ brown_900="#3E2723",
+
+ --grey
+ grey_50="#FAFAFA",
+ grey_100="#F5F5F5",
+ grey_200="#EEEEEE",
+ grey_300="#E0E0E0",
+ grey_400="#BDBDBD",
+ grey_500="#9E9E9E",
+ grey_600="#757575",
+ grey_700="#616161",
+ grey_800="#424242",
+ grey_900="#212121",
+ black_1000="#000000",
+ white_1000="#ffffff",
+
+ --blue grey
+ blue_grey_50="#ECEFF1",
+ blue_grey_100="#CFD8DC",
+ blue_grey_200="#B0BBC5",
+ blue_grey_300="#90A4AE",
+ blue_grey_400="#78909C",
+ blue_grey_500="#607D8B",
+ blue_grey_600="#546E7A",
+ blue_grey_700="#455A64",
+ blue_grey_800="#37474F",
+ blue_grey_900="#263238",
+}
diff --git a/main/actions-widget.lua b/main/actions-widget.lua
new file mode 100644
index 0000000..c37498c
--- /dev/null
+++ b/main/actions-widget.lua
@@ -0,0 +1,17 @@
+-- name = "Actions"
+-- description = "Launcher actions widget"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_resume()
+ actions_names = { "Drawer", "Search", "Notify", "Menu" }
+ actions_colors = { md_colors.purple_800, md_colors.purple_600, md_colors.purple_400, md_colors.purple_300 }
+ actions = { "apps_menu", "search", "notify", "quick_menu" }
+
+ ui:show_buttons(actions_names, actions_colors)
+end
+
+function on_click(idx)
+ aio:do_action(actions[idx])
+end
diff --git a/main/btc-widget.lua b/main/btc-widget.lua
new file mode 100644
index 0000000..009ecb4
--- /dev/null
+++ b/main/btc-widget.lua
@@ -0,0 +1,16 @@
+-- name = "Bitcoin price"
+-- description = "Current Bitcoin price (blockchain.info)"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+equals = " = "
+
+function on_alarm()
+ http:get("https://api.blockchain.info/ticker")
+end
+
+function on_network_result(result)
+ local price = ajson:get_value(result, "object object:USD string:last")
+ ui:show_text("1 BTC"..equals..price.." USD")
+end
diff --git a/main/clipboard-widget.lua b/main/clipboard-widget.lua
new file mode 100644
index 0000000..1fa666c
--- /dev/null
+++ b/main/clipboard-widget.lua
@@ -0,0 +1,9 @@
+-- name = "Clipboard"
+-- description = "Shows current Clipboard contents"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_resume()
+ ui:show_text(system:get_from_clipboard())
+end
diff --git a/main/covid-widget.lua b/main/covid-widget.lua
new file mode 100644
index 0000000..c0f934c
--- /dev/null
+++ b/main/covid-widget.lua
@@ -0,0 +1,30 @@
+-- name = "Covid info"
+-- description = "Cases of illness and death from covid"
+-- data_source = "covid19api.com"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+equals = " = "
+
+function on_alarm()
+ http:get("https://api.covid19api.com/summary")
+end
+
+function on_network_result(result)
+ local new = ajson:get_value(result, "object object:Global int:NewConfirmed")
+ local total = ajson:get_value(result, "object object:Global int:TotalConfirmed")
+ local newDeaths = ajson:get_value(result, "object object:Global int:NewDeaths")
+ local totalDeaths = ajson:get_value(result, "object object:Global int:TotalDeaths")
+
+ ui:show_lines({
+ "Disease | total"..equals..comma_value(total).." | new"..equals..comma_value(new),
+ "Deaths | total"..equals..comma_value(totalDeaths).." | new"..equals..comma_value(newDeaths)
+ })
+end
+
+function comma_value(n) -- credit http://richard.warburton.it
+ local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
+ return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
+end
+
diff --git a/main/currencies-widget.lua b/main/currencies-widget.lua
new file mode 100644
index 0000000..c2d001f
--- /dev/null
+++ b/main/currencies-widget.lua
@@ -0,0 +1,105 @@
+-- name = "Currencies"
+-- description = "Currency rates widget. Click on the date to change it."
+-- data_source = "https://github.com/fawazahmed0/currency-api#readme"
+-- type = "widget"
+-- author = "Andrey Gavrilov"
+-- version = "1.0"
+-- arguments_help = "Enter the list of currency pairs in the format usd:rub btc:usd"
+-- arguments_default = "usd:rub eur:rub"
+
+json = require "json"
+
+-- constants
+local red_color = "#f44336"
+local green_color = "#48ad47"
+local text_color = ui:get_secondary_text_color()
+local equals = " = "
+
+-- global vars
+local result_curr = ""
+local tabl = {}
+
+function on_resume()
+ ui:set_folding_flag(true)
+ ui:show_lines(tabl)
+end
+
+function on_alarm()
+ get_rates("latest", "curr")
+end
+
+function get_rates(loc_date,id)
+ http:get("https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/"..loc_date.."/currencies/usd.json",id)
+end
+
+function on_network_result_curr(result)
+ result_curr = result
+
+ local t = json.decode(result)
+ local dat = t.date
+ local prev_date = prev_date(dat)
+
+ get_rates(prev_date, "prev")
+end
+
+function on_network_result_prev(result)
+ tabl = create_tab(result)
+ ui:show_lines(tabl)
+end
+
+function on_click(idx)
+ ui:show_edit_dialog("Введите дату курсов", "Введите дату курсов в формате 2020.12.31. Пустое значение - текущая дата.")
+end
+
+function on_dialog_action(dat)
+ if dat == "" then dat = "latest" end
+ get_rates(dat:gsub(".", "-"), "curr")
+end
+
+function prev_date(dat)
+ local prev_date = dat:split("-")
+ local prev_time = os.time{year=prev_date[1], month=prev_date[2], day=prev_date[3]} - (60*60*24)
+ return os.date("%Y-%m-%d", prev_time)
+end
+
+function create_tab(result)
+ local curs = aio:get_args()
+ local tab = {}
+ local t_c = json.decode(result_curr)
+ local t_p = json.decode(result)
+
+ -- set title
+ local dat = t_c.date
+ ui:set_title(ui:get_default_title().." "..dat:gsub("-", "."))
+
+ for idx = 1, #curs, 1 do
+ local cur = curs[idx]:split(":")
+
+ local rate_curr1 = t_c.usd[cur[1]]
+ local rate_curr2 = t_c.usd[cur[2]]
+ local rate_prev1 = t_p.usd[cur[1]]
+ local rate_prev2 = t_p.usd[cur[2]]
+
+ local rate_curr = round(rate_curr2/rate_curr1, 4)
+ local rate_prev = round(rate_prev2/rate_prev1, 4)
+ local change = round((rate_curr-rate_prev)/rate_prev*100,2)
+
+ local line = "1 "..string.upper(cur[1])..equals..rate_curr.." "..string.upper(cur[2])
+ line = line..get_formatted_change_text(change)
+
+ table.insert(tab, line)
+ end
+ return tab
+end
+
+-- utils --
+
+function get_formatted_change_text(change)
+ if change > 0 then
+ return " +"..change.."%"
+ elseif change < 0 then
+ return " "..change.."%"
+ else
+ return " "..change.."%"
+ end
+end
diff --git a/main/github-trending-widget.lua b/main/github-trending-widget.lua
new file mode 100644
index 0000000..5be2d5f
--- /dev/null
+++ b/main/github-trending-widget.lua
@@ -0,0 +1,35 @@
+-- name = "GitHub Trending"
+-- description = "GitHub trending repositories (trending-github.com)"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("https://api.trending-github.com/github/repositories")
+end
+
+function on_network_result(result)
+ local names = {
+ ajson:get_value(result, "array object:0 string:name"),
+ ajson:get_value(result, "array object:1 string:name"),
+ ajson:get_value(result, "array object:2 string:name"),
+ }
+
+ local descriptions = {
+ ajson:get_value(result, "array object:0 string:description"),
+ ajson:get_value(result, "array object:1 string:description"),
+ ajson:get_value(result, "array object:2 string:description"),
+ }
+
+ urls = {
+ ajson:get_value(result, "array object:0 string:url"),
+ ajson:get_value(result, "array object:1 string:url"),
+ ajson:get_value(result, "array object:2 string:url"),
+ }
+
+ ui:show_lines(names, descriptions)
+end
+
+function on_click(idx)
+ system:open_browser(urls[idx])
+end
diff --git a/main/icndb-widget.lua b/main/icndb-widget.lua
new file mode 100644
index 0000000..cbcc050
--- /dev/null
+++ b/main/icndb-widget.lua
@@ -0,0 +1,15 @@
+-- name = "Chuck Norris jokes"
+-- description = "icndb.com"
+-- data_source = "icndb.com"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("http://api.icndb.com/jokes/random")
+end
+
+function on_network_result(result)
+ local joke = ajson:get_value(result, "object object:value string:joke")
+ ui:show_text(joke)
+end
diff --git a/main/inspiration-quotes-widget.lua b/main/inspiration-quotes-widget.lua
new file mode 100644
index 0000000..125db1c
--- /dev/null
+++ b/main/inspiration-quotes-widget.lua
@@ -0,0 +1,17 @@
+-- name = "Inspiration quotes"
+-- description = "inspiration.goprogram.ai"
+-- data_source = "inspiration.goprogram.ai"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("https://inspiration.goprogram.ai/")
+end
+
+function on_network_result(result)
+ local quote = ajson:get_value(result, "object string:quote")
+ local author = ajson:get_value(result, "object string:author")
+
+ ui:show_lines({ quote }, { author })
+end
diff --git a/main/public-ip-widget.lua b/main/public-ip-widget.lua
new file mode 100644
index 0000000..bfe2641
--- /dev/null
+++ b/main/public-ip-widget.lua
@@ -0,0 +1,14 @@
+-- name = "Public IP"
+-- description = "Shows your public IP (ipify.org)"
+-- data_source = "ipify.org"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("https://api.ipify.org")
+end
+
+function on_network_result(result)
+ ui:show_text(result)
+end
diff --git a/main/quotes-widget.lua b/main/quotes-widget.lua
new file mode 100644
index 0000000..50ae02d
--- /dev/null
+++ b/main/quotes-widget.lua
@@ -0,0 +1,17 @@
+-- name = "Random quotes"
+-- description = "quotable.io"
+-- data_source = "quotable.io"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("https://api.quotable.io/random")
+end
+
+function on_network_result(result)
+ local quote = ajson:get_value(result, "object string:content")
+ local author = ajson:get_value(result, "object string:author")
+
+ ui:show_lines({ quote }, { author })
+end
diff --git a/main/random-joke-widget.lua b/main/random-joke-widget.lua
new file mode 100644
index 0000000..d8ae788
--- /dev/null
+++ b/main/random-joke-widget.lua
@@ -0,0 +1,16 @@
+-- name = "Random jokes"
+-- description = "official-joke-api.appspot.com"
+-- data_source = "official-joke-api.appspot.com"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("https://official-joke-api.appspot.com/random_joke")
+end
+
+function on_network_result(result)
+ local setup = ajson:get_value(result, "object string:setup")
+ local punchline = ajson:get_value(result, "object string:punchline")
+ ui:show_lines({setup, punchline})
+end
diff --git a/main/rss-widget.lua b/main/rss-widget.lua
new file mode 100644
index 0000000..c01a7b0
--- /dev/null
+++ b/main/rss-widget.lua
@@ -0,0 +1,54 @@
+-- name = "News"
+-- description = "Simple RSS news widget"
+-- data_source = "https://rss-to-json-serverless-api.vercel.app/"
+-- type = "widget"
+-- author = "Andrey Gavrilov"
+-- version = "1.0"
+
+-- settings
+local feed = "https://news.yandex.ru/index.rss"
+local lines_num = 5
+local auto_folding = false
+
+local api_url = "https://rss-to-json-serverless-api.vercel.app/api?feedURL="
+local titles = {}
+local descs = {}
+local urls = {}
+local times = {}
+local url = ""
+
+local json = require "json"
+
+function on_resume()
+ if auto_folding then
+ ui:set_folding_flag(true)
+ ui:show_lines(titles)
+ end
+end
+
+function on_alarm()
+ http:get(api_url..feed)
+end
+
+function on_network_result(result)
+ local t = json.decode(result)
+ local n = math.min(lines_num, #t.items)
+ for i = 1, n, 1 do
+ titles[i] = t.items[i].title
+ descs[i] = t.items[i].description
+ urls[i] = t.items[i].url
+ times[i] = os.date("%d.%m.%Y, %H:%M",t.items[i].created/1000)
+ end
+ ui:show_lines(titles)
+end
+
+function on_click(i)
+ url = urls[i]
+ ui:show_dialog(titles[i].." | "..times[i], descs[i], "open in browser")
+end
+
+function on_dialog_action(i)
+ if i == 1 then
+ system:open_browser(url)
+ end
+end
diff --git a/main/shell-widget.lua b/main/shell-widget.lua
new file mode 100644
index 0000000..d4cd858
--- /dev/null
+++ b/main/shell-widget.lua
@@ -0,0 +1,29 @@
+-- name = "Shell widget"
+-- description = "Shows the result of executing console commands"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+current_output = "Click to enter command"
+
+function on_resume()
+ redraw()
+end
+
+function redraw()
+ ui:show_text(current_output)
+end
+
+function on_click(idx)
+ ui:show_edit_dialog("Enter command")
+end
+
+function on_dialog_action(text)
+ system:exec(text)
+end
+
+function on_shell_result(text)
+ current_output = text
+ redraw()
+end
+
diff --git a/main/year_progress-widget.lua b/main/year_progress-widget.lua
new file mode 100644
index 0000000..a22ec9c
--- /dev/null
+++ b/main/year_progress-widget.lua
@@ -0,0 +1,12 @@
+-- name = "Year progress"
+-- description = "Shows current year progress"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_resume()
+ local year_days = 365
+ local current_day = os.date("*t").yday
+ local percent = math.floor(current_day / (year_days / 100))
+ ui:show_progress_bar("Year progress: "..percent.."%", current_day, year_days)
+end
diff --git a/ru/holydays-ru-widget.lua b/ru/holydays-ru-widget.lua
new file mode 100644
index 0000000..eda6870
--- /dev/null
+++ b/ru/holydays-ru-widget.lua
@@ -0,0 +1,38 @@
+-- name = "Праздники"
+-- description = "Виджет отображает предстоящие праздники."
+-- data_source = "https://date.nager.at/"
+-- type = "widget"
+-- author = "Andrey Gavrilov"
+-- version = "1.0"
+
+--API--
+local api_url = "https://date.nager.at/api/v3/NextPublicHolidays/RU"
+
+--Настройка автосворачивания виджета--
+local auto_folding = false
+
+local lines = {}
+
+local json = require "json"
+local sx = require "pl.stringx"
+
+function on_resume()
+ if auto_folding then
+ ui:set_folding_flag(true)
+ ui:show_lines(lines)
+ end
+end
+
+function on_alarm()
+ http:get(api_url)
+end
+
+function on_network_result(result)
+ local t = json.decode(result)
+ for i = 1, #t, 1 do
+ local date = sx.replace(t[i].date, "-", ".")
+ local name = t[i].localName
+ lines[i] = date.." - "..name
+ end
+ ui:show_lines(lines)
+end
diff --git a/ru/isdayoff-ru-widget.lua b/ru/isdayoff-ru-widget.lua
new file mode 100644
index 0000000..6356226
--- /dev/null
+++ b/ru/isdayoff-ru-widget.lua
@@ -0,0 +1,21 @@
+-- name = "Сегодня выходной?"
+-- description = "Показывает, выходной ли сегодня день."
+-- data_source = "isdayoff.ru"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ local dateStr = os.date('%Y%m%d')
+ http:get("https://isdayoff.ru/"..dateStr)
+end
+
+function on_network_result(result)
+ if result == "0" then
+ ui:show_text("Сегодня рабочий день")
+ elseif result == "1" then
+ ui:show_text("Сегодня выходной")
+ else
+ ui:show_text("Ошибка")
+ end
+end
diff --git a/ru/quotes-ru-widget.lua b/ru/quotes-ru-widget.lua
new file mode 100644
index 0000000..0ae7562
--- /dev/null
+++ b/ru/quotes-ru-widget.lua
@@ -0,0 +1,17 @@
+-- name = "Цитаты великих"
+-- description = "Рандомные цитаты на русском языке."
+-- data_source = "forismatic.com"
+-- type = "widget"
+-- author = "Evgeny Zobnin (zobnin@gmail.com)"
+-- version = "1.0"
+
+function on_alarm()
+ http:get("http://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=ru")
+end
+
+function on_network_result(result)
+ local quote = ajson:get_value(result, "object string:quoteText")
+ local author = ajson:get_value(result, "object string:quoteAuthor")
+
+ ui:show_lines({ quote }, { author })
+end
diff --git a/ru/widgets-on-off.lua b/ru/widgets-on-off.lua
new file mode 100644
index 0000000..88134cc
--- /dev/null
+++ b/ru/widgets-on-off.lua
@@ -0,0 +1,55 @@
+-- name = "Включение виджетов"
+-- description = "Включает и отключает виджеты на экране при нажатии на кнопки"
+-- type = "widget"
+-- author = "Andrey Gavrilov"
+-- version = "1.0"
+-- arguments_help = "Введите список виджетов и кнопок в формате bitcoin:Биткойн timer:Таймер"
+-- arguments_default = "bitcoin:Битк. timer:Тайм. stopwatch:Секунд. recorder:Дикт. calculator:Кальк."
+
+sx = require 'pl.stringx'
+
+function on_resume()
+ local args = get_args_kv()
+
+ widgets = args[1]
+ buttons = args[2]
+ colors = {}
+
+ for idx,widget in ipairs(widgets) do
+ if aio:is_widget_added(widget) then
+ colors[idx] = md_colors.red_500
+ else
+ colors[idx] = md_colors.green_500
+ end
+ end
+
+ ui:show_buttons(buttons, colors)
+end
+
+function on_click(idx)
+ local widget = widgets[idx]
+
+ if aio:is_widget_added(widget) then
+ aio:remove_widget(widget)
+ colors[idx] = md_colors.green_500
+ else
+ aio:add_widget(widget)
+ colors[idx] = md_colors.red_500
+ end
+
+ ui:show_buttons(buttons, colors)
+end
+
+function get_args_kv()
+ local keys = {}
+ local values = {}
+ local args = aio:get_args()
+
+ for idx = 1, #args, 1 do
+ local arg = sx.split(args[idx], ":")
+ keys[idx] = arg[1]
+ values[idx] = arg[2]
+ end
+
+ return { keys, values }
+end
diff --git a/samples/app-buttons-sample.lua b/samples/app-buttons-sample.lua
new file mode 100644
index 0000000..c2d1984
--- /dev/null
+++ b/samples/app-buttons-sample.lua
@@ -0,0 +1,11 @@
+function on_resume()
+ apps_names = { "Telegram", "WhatsApp", "Google PLay" }
+ apps_pkgs = { "org.telegram.messenger.web", "com.whatsapp", "com.android.vending" }
+ apps_colors = { md_colors.light_blue_500, md_colors.green_500 }
+
+ ui:show_buttons(apps_names, apps_colors)
+end
+
+function on_click(idx)
+ system:open_app(apps_pkgs[idx])
+end
diff --git a/samples/args-test.lua b/samples/args-test.lua
new file mode 100644
index 0000000..63c7abf
--- /dev/null
+++ b/samples/args-test.lua
@@ -0,0 +1,12 @@
+-- arguments_help = "The word recorded here will be displayed on the screen."
+-- arguments_default = "Word"
+
+function on_resume()
+ local args = aio:get_args()
+
+ if args == nil then
+ ui:show_text("args is empty")
+ else
+ ui:show_text("arg1: "..args[1])
+ end
+end
diff --git a/samples/auto-folding-test.lua b/samples/auto-folding-test.lua
new file mode 100644
index 0000000..0d86df9
--- /dev/null
+++ b/samples/auto-folding-test.lua
@@ -0,0 +1,4 @@
+function on_resume()
+ ui:set_folding_flag(true)
+ ui:show_lines({"First line", "Second line", "Third line"})
+end
diff --git a/samples/bad-script.lua b/samples/bad-script.lua
new file mode 100644
index 0000000..85cde84
--- /dev/null
+++ b/samples/bad-script.lua
@@ -0,0 +1,9 @@
+function on_resume()
+ ui:show_text("Click to freeze launcher")
+end
+
+function on_click()
+ while true do
+ system:copy_to_clipboard("http://google.com")
+ end
+end
diff --git a/samples/bad-script2.lua b/samples/bad-script2.lua
new file mode 100644
index 0000000..e38da0e
--- /dev/null
+++ b/samples/bad-script2.lua
@@ -0,0 +1,5 @@
+function on_resume()
+ while true do
+ ui:show_text("Haha")
+ end
+end
diff --git a/samples/bad-script3.lua b/samples/bad-script3.lua
new file mode 100644
index 0000000..102216e
--- /dev/null
+++ b/samples/bad-script3.lua
@@ -0,0 +1,2 @@
+ui:show_toast("Hello")
+
diff --git a/samples/bad-script4.lua b/samples/bad-script4.lua
new file mode 100644
index 0000000..bb7bf92
--- /dev/null
+++ b/samples/bad-script4.lua
@@ -0,0 +1,5 @@
+function on_tick()
+ while true do
+ ui:show_text("bad")
+ end
+end
diff --git a/samples/buttons_with_state_sample.lua b/samples/buttons_with_state_sample.lua
new file mode 100644
index 0000000..858858a
--- /dev/null
+++ b/samples/buttons_with_state_sample.lua
@@ -0,0 +1,19 @@
+buttons = { "Disabled", "Disabled", "Disabled" }
+
+function on_resume()
+ redraw()
+end
+
+function on_click(idx)
+ if buttons[idx] == "Disabled" then
+ buttons[idx] = "Enabled"
+ else
+ buttons[idx] = "Disabled"
+ end
+
+ redraw()
+end
+
+function redraw()
+ ui:show_buttons(buttons)
+end
diff --git a/samples/checkbox-dialog-sample.lua b/samples/checkbox-dialog-sample.lua
new file mode 100644
index 0000000..c800cfd
--- /dev/null
+++ b/samples/checkbox-dialog-sample.lua
@@ -0,0 +1,16 @@
+function on_resume()
+ ui:show_text("Open dialog")
+end
+
+function on_click()
+ dialog_items = { "One", "Two", "Three" }
+ ui:show_checkbox_dialog("Title", dialog_items, 2)
+end
+
+function on_dialog_action(idx)
+ if idx == -1 then
+ ui:show_toast("Dialog cancelled")
+ else
+ ui:show_toast("Checked: "..dialog_items[idx])
+ end
+end
diff --git a/samples/clock-widget.lua b/samples/clock-widget.lua
new file mode 100644
index 0000000..8a12d3f
--- /dev/null
+++ b/samples/clock-widget.lua
@@ -0,0 +1,4 @@
+function on_tick()
+ local time_str = os.date('%Y-%m-%d %H:%M:%S')
+ ui:show_text(time_str)
+end
diff --git a/samples/coroutines-test.lua b/samples/coroutines-test.lua
new file mode 100644
index 0000000..a8cfeb2
--- /dev/null
+++ b/samples/coroutines-test.lua
@@ -0,0 +1,11 @@
+local co = coroutine.create(function()
+ while true do
+ ui:show_text("Hello world!")
+ coroutine.yield()
+ end
+end)
+
+function on_resume()
+ ui:set_title(coroutine.status(co))
+ coroutine.resume(co)
+end
diff --git a/samples/dialog_sample.lua b/samples/dialog_sample.lua
new file mode 100644
index 0000000..716cbd5
--- /dev/null
+++ b/samples/dialog_sample.lua
@@ -0,0 +1,27 @@
+function on_resume()
+ ui:show_lines({
+ "Click to open dialog",
+ "Click to open dialog with custom buttons",
+ "Click to open edit dialog",
+ })
+end
+
+function on_click(idx)
+ if idx == 1 then
+ ui:show_dialog("Dialog title", "This is dialog")
+ elseif idx == 2 then
+ ui:show_dialog("Dialog title", "This is dialog", "Button 1", "Button 2")
+ elseif idx == 3 then
+ ui:show_edit_dialog("Dialog title", "Write any text", "default text")
+ end
+end
+
+function on_dialog_action(value)
+ if value == 1 then
+ ui:show_toast("Button 1 clicked!")
+ elseif value == 2 then
+ ui:show_toast("Button 2 clicked!")
+ elseif type(value) == "string" then
+ ui:show_toast("Text: "..value)
+ end
+end
diff --git a/samples/hello_world-widget.lua b/samples/hello_world-widget.lua
new file mode 100644
index 0000000..7a05f9b
--- /dev/null
+++ b/samples/hello_world-widget.lua
@@ -0,0 +1,3 @@
+function on_resume()
+ ui:show_text("Hello world!")
+end
diff --git a/samples/html_test.lua b/samples/html_test.lua
new file mode 100644
index 0000000..cb10a26
--- /dev/null
+++ b/samples/html_test.lua
@@ -0,0 +1,3 @@
+function on_resume()
+ ui:show_lines({ "This is bold text" })
+end
diff --git a/samples/ip-location-widget.lua b/samples/ip-location-widget.lua
new file mode 100644
index 0000000..9a7a245
--- /dev/null
+++ b/samples/ip-location-widget.lua
@@ -0,0 +1,20 @@
+ip_service_url = "https://freegeoip.app/json/"
+addr_service_url = "https://nominatim.openstreetmap.org/reverse?format=json"
+
+function on_alarm()
+ http:get(ip_service_url, "ip")
+end
+
+function on_network_result_ip(result)
+ local location = {
+ ajson:get_value(result, "object string:latitude"),
+ ajson:get_value(result, "object string:longitude")
+ }
+ http:get(addr_service_url.."&lat="..location[1].."&lon=".. location[2].."&addressdetails=1", "addr")
+end
+
+function on_network_result_addr(result)
+ local adr = ajson:get_value(result, "object string:display_name")
+ ui:show_text(adr)
+end
+
diff --git a/samples/is_widget_added_sample.lua b/samples/is_widget_added_sample.lua
new file mode 100644
index 0000000..c01bed4
--- /dev/null
+++ b/samples/is_widget_added_sample.lua
@@ -0,0 +1,3 @@
+function on_resume()
+ ui:show_text("Mail widget on the screen: " .. tostring(aio:is_widget_added("mail")))
+end
diff --git a/samples/json-test.lua b/samples/json-test.lua
new file mode 100644
index 0000000..85d5b8e
--- /dev/null
+++ b/samples/json-test.lua
@@ -0,0 +1,6 @@
+json = require "json"
+
+function on_resume()
+ local t = json.decode('[1,2,3,{"x":10}]')
+ ui:show_text(t[4].x)
+end
diff --git a/samples/location-widget.lua b/samples/location-widget.lua
new file mode 100644
index 0000000..c10a4b2
--- /dev/null
+++ b/samples/location-widget.lua
@@ -0,0 +1,4 @@
+function on_resume()
+ local location = system:get_location()
+ ui:show_text(location[1].." "..location[2])
+end
diff --git a/samples/pl-tests.lua b/samples/pl-tests.lua
new file mode 100644
index 0000000..6f59ed6
--- /dev/null
+++ b/samples/pl-tests.lua
@@ -0,0 +1,7 @@
+sx = require 'pl.stringx'
+
+function on_resume()
+ local string = "String with spaces"
+ local s_list = sx.split(string, " ")
+ ui:show_text(s_list[3])
+end
diff --git a/samples/place-widget.lua b/samples/place-widget.lua
new file mode 100644
index 0000000..aecc0a4
--- /dev/null
+++ b/samples/place-widget.lua
@@ -0,0 +1,9 @@
+function on_alarm()
+ local location = system:get_location()
+ http:get("https://nominatim.openstreetmap.org/reverse?format=json&lat=".. location[1].."&lon=".. location[2].."&addressdetails=1")
+end
+
+function on_network_result(result)
+ local adr = ajson:get_value(result, "object string:display_name")
+ ui:show_text(adr)
+end
diff --git a/samples/print-error.lua b/samples/print-error.lua
new file mode 100644
index 0000000..5a84de9
--- /dev/null
+++ b/samples/print-error.lua
@@ -0,0 +1,5 @@
+function print_hello()
+ print("HELLO")
+end
+
+print_hello()
diff --git a/samples/test-return-code.lua b/samples/test-return-code.lua
new file mode 100644
index 0000000..fec8ed4
--- /dev/null
+++ b/samples/test-return-code.lua
@@ -0,0 +1,7 @@
+function on_resume()
+ http:get("https://google.com")
+end
+
+function on_network_result(body, code)
+ ui:show_text(code)
+end
diff --git a/samples/title-sample.lua b/samples/title-sample.lua
new file mode 100644
index 0000000..8db6efa
--- /dev/null
+++ b/samples/title-sample.lua
@@ -0,0 +1,4 @@
+function on_resume()
+ ui:set_title("New title")
+ ui:show_text("Original title: "..ui:get_default_title())
+end
diff --git a/samples/utils-sample.lua b/samples/utils-sample.lua
new file mode 100644
index 0000000..c11e484
--- /dev/null
+++ b/samples/utils-sample.lua
@@ -0,0 +1,5 @@
+function on_resume()
+ local str = "one two three"
+ local tab = str:split(" ")
+ ui:show_text(tab[2])
+end
diff --git a/samples/widget_add_remove_sample.lua b/samples/widget_add_remove_sample.lua
new file mode 100644
index 0000000..e56921c
--- /dev/null
+++ b/samples/widget_add_remove_sample.lua
@@ -0,0 +1,11 @@
+function on_resume()
+ ui:show_buttons({ "Add clock widget", "Remove clock widget" })
+end
+
+function on_click(idx)
+ if idx == 1 then
+ aio:add_widget("clock")
+ else
+ aio:remove_widget("clock")
+ end
+end
diff --git a/sandbox.lua b/sandbox.lua
deleted file mode 100644
index 58f9dfc..0000000
--- a/sandbox.lua
+++ /dev/null
@@ -1,10 +0,0 @@
-function sandbox(func)
- local co = coroutine.create(func)
- local hook = function() coroutine.yield('resource used too many cycles') end
-
- debug.setupvalue(func, 1, _G)
- debug.sethook(co, hook, "", 100)
-
- coroutine.resume(co)
-end
-
diff --git a/widgets-on-off.lua b/widgets-on-off.lua
index 7017e3c..88134cc 100644
--- a/widgets-on-off.lua
+++ b/widgets-on-off.lua
@@ -17,9 +17,9 @@ function on_resume()
for idx,widget in ipairs(widgets) do
if aio:is_widget_added(widget) then
- colors[idx] = "#f44336"
+ colors[idx] = md_colors.red_500
else
- colors[idx] = "#388e3c"
+ colors[idx] = md_colors.green_500
end
end
@@ -31,10 +31,10 @@ function on_click(idx)
if aio:is_widget_added(widget) then
aio:remove_widget(widget)
- colors[idx] = "#388e3c"
+ colors[idx] = md_colors.green_500
else
aio:add_widget(widget)
- colors[idx] = "#f44336"
+ colors[idx] = md_colors.red_500
end
ui:show_buttons(buttons, colors)