mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2026-01-08 20:22:38 +01:00
Обновленное приложение "погода" и фикс ебучего Файндера
This commit is contained in:
parent
855ce535e3
commit
44adbf2808
@ -239,7 +239,7 @@
|
||||
path="/lib/MineOSInterface.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/MineOSInterface.lua",
|
||||
type="Library",
|
||||
version=1.26,
|
||||
version=1.27,
|
||||
},
|
||||
{
|
||||
path="/lib/MineOSPaths.lua",
|
||||
@ -596,7 +596,7 @@
|
||||
type="Application",
|
||||
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/Icon.pic",
|
||||
forceDownload=true,
|
||||
version=1.37,
|
||||
version=1.38,
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Weather",
|
||||
@ -605,7 +605,7 @@
|
||||
type="Application",
|
||||
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Weather/Icon.pic",
|
||||
createShortcut=true,
|
||||
version=1.18,
|
||||
version=1.19,
|
||||
resources={
|
||||
{
|
||||
path="/Cloudy.pic",
|
||||
@ -632,8 +632,8 @@
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Weather/Sunny.pic",
|
||||
},
|
||||
{
|
||||
path="/SunnyWithClouds.pic",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Weather/SunnyWithClouds.pic",
|
||||
path="/Foggy.pic",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Weather/Foggy.pic",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -938,7 +938,7 @@
|
||||
type="Application",
|
||||
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Photoshop/Icon.pic",
|
||||
forceDownload=true,
|
||||
version=1.11,
|
||||
version=1.12,
|
||||
resources={
|
||||
{
|
||||
path="/Localization/Russian.lang",
|
||||
|
||||
@ -196,7 +196,7 @@ window.iconField.launchers.showPackageContent = function(icon)
|
||||
end
|
||||
|
||||
window.iconField.launchers.showContainingFolder = function(icon)
|
||||
addWorkpath(fs.path(icon.path))
|
||||
addWorkpath(fs.path(MineOSCore.readShortcut(icon.path)))
|
||||
updateFileListAndDraw()
|
||||
end
|
||||
|
||||
|
||||
0
Applications/Weather/Cloudy.pic
Normal file → Executable file
0
Applications/Weather/Cloudy.pic
Normal file → Executable file
BIN
Applications/Weather/Foggy.pic
Executable file
BIN
Applications/Weather/Foggy.pic
Executable file
Binary file not shown.
Binary file not shown.
0
Applications/Weather/Rainy.pic
Normal file → Executable file
0
Applications/Weather/Rainy.pic
Normal file → Executable file
BIN
Applications/Weather/Snowy.pic
Normal file → Executable file
BIN
Applications/Weather/Snowy.pic
Normal file → Executable file
Binary file not shown.
0
Applications/Weather/Stormy.pic
Normal file → Executable file
0
Applications/Weather/Stormy.pic
Normal file → Executable file
Binary file not shown.
Binary file not shown.
@ -1,11 +1,7 @@
|
||||
|
||||
---------------------------------------------------- Библиотеки ----------------------------------------------------------------
|
||||
|
||||
require("advancedLua")
|
||||
local web = require("web")
|
||||
local json = require("json")
|
||||
local serialization = require("serialization")
|
||||
local event = require("event")
|
||||
local ecs = require("ECSAPI")
|
||||
local fs = require("filesystem")
|
||||
local bigLetters = require("bigLetters")
|
||||
local buffer = require("doubleBuffering")
|
||||
@ -14,285 +10,142 @@ local unicode = require("unicode")
|
||||
local component = require("component")
|
||||
local GUI = require("GUI")
|
||||
local MineOSCore = require("MineOSCore")
|
||||
local MineOSInterface = require("MineOSInterface")
|
||||
local MineOSPaths = require("MineOSPaths")
|
||||
|
||||
---------------------------------------------------- Константы ----------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
local weather = {}
|
||||
local changeCityButton = {}
|
||||
local exitButton = {}
|
||||
local mainContainer, window = MineOSInterface.addWindow(MineOSInterface.filledWindow(1, 1, 130, 30, 0))
|
||||
window.backgroundPanel.colors.transparency = 0.2
|
||||
|
||||
local weatherContainer = window:addChild(GUI.container(1, 1, 1, 23))
|
||||
|
||||
local resources = MineOSCore.getCurrentApplicationResourcesDirectory()
|
||||
local pathToWeatherFile = MineOSPaths.applicationData .. "Weather/Forecast.cfg"
|
||||
|
||||
local pathsToWeatherTypes = {
|
||||
sunny = resources .. "Sunny.pic",
|
||||
sunnyWithClouds = resources .. "SunnyWithClouds.pic",
|
||||
snowy = resources .. "Snowy.pic",
|
||||
rainy = resources .. "Rainy.pic",
|
||||
cloudy = resources .. "Cloudy.pic",
|
||||
stormy = resources .. "Stormy.pic",
|
||||
}
|
||||
|
||||
local weatherIcons = {
|
||||
[0] = pathsToWeatherTypes.stormy,
|
||||
[1] = pathsToWeatherTypes.stormy,
|
||||
[2] = pathsToWeatherTypes.stormy,
|
||||
[3] = pathsToWeatherTypes.stormy,
|
||||
[4] = pathsToWeatherTypes.stormy,
|
||||
[5] = pathsToWeatherTypes.rainy,
|
||||
[6] = pathsToWeatherTypes.rainy,
|
||||
[7] = pathsToWeatherTypes.rainy,
|
||||
[8] = pathsToWeatherTypes.rainy,
|
||||
[9] = pathsToWeatherTypes.rainy,
|
||||
[10] = pathsToWeatherTypes.rainy,
|
||||
[11] = pathsToWeatherTypes.rainy,
|
||||
[12] = pathsToWeatherTypes.rainy,
|
||||
[13] = pathsToWeatherTypes.snowy,
|
||||
[14] = pathsToWeatherTypes.snowy,
|
||||
[15] = pathsToWeatherTypes.snowy,
|
||||
[16] = pathsToWeatherTypes.snowy,
|
||||
[17] = pathsToWeatherTypes.snowy,
|
||||
[18] = pathsToWeatherTypes.rainy,
|
||||
[19] = pathsToWeatherTypes.cloudy,
|
||||
[20] = pathsToWeatherTypes.cloudy,
|
||||
[21] = pathsToWeatherTypes.cloudy,
|
||||
[22] = pathsToWeatherTypes.cloudy,
|
||||
[23] = pathsToWeatherTypes.cloudy,
|
||||
[24] = pathsToWeatherTypes.cloudy,
|
||||
[25] = pathsToWeatherTypes.cloudy,
|
||||
[26] = pathsToWeatherTypes.cloudy,
|
||||
[27] = pathsToWeatherTypes.cloudy,
|
||||
[28] = pathsToWeatherTypes.cloudy,
|
||||
[29] = pathsToWeatherTypes.sunnyWithClouds,
|
||||
[30] = pathsToWeatherTypes.sunnyWithClouds,
|
||||
[31] = pathsToWeatherTypes.sunny,
|
||||
[32] = pathsToWeatherTypes.sunny,
|
||||
[33] = pathsToWeatherTypes.sunny,
|
||||
[34] = pathsToWeatherTypes.sunny,
|
||||
[35] = pathsToWeatherTypes.rainy,
|
||||
[36] = pathsToWeatherTypes.sunny,
|
||||
[37] = pathsToWeatherTypes.stormy,
|
||||
[38] = pathsToWeatherTypes.stormy,
|
||||
[39] = pathsToWeatherTypes.stormy,
|
||||
[40] = pathsToWeatherTypes.rainy,
|
||||
[41] = pathsToWeatherTypes.snowy,
|
||||
[42] = pathsToWeatherTypes.snowy,
|
||||
[43] = pathsToWeatherTypes.snowy,
|
||||
[44] = pathsToWeatherTypes.sunnyWithClouds,
|
||||
[45] = pathsToWeatherTypes.stormy,
|
||||
[46] = pathsToWeatherTypes.snowy,
|
||||
[47] = pathsToWeatherTypes.stormy,
|
||||
sunny = image.load(resources .. "Sunny.pic"),
|
||||
sunnyAndCloudy = image.load(resources .. "Icon.pic"),
|
||||
snowy = image.load(resources .. "Snowy.pic"),
|
||||
rainy = image.load(resources .. "Rainy.pic"),
|
||||
cloudy = image.load(resources .. "Cloudy.pic"),
|
||||
thundery = image.load(resources .. "Stormy.pic"),
|
||||
foggy = image.load(resources .. "Foggy.pic"),
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
--Запрос на получение погоды
|
||||
local function weatherRequest(city)
|
||||
local url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22" .. city .. "%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
|
||||
local success, response = ecs.internetRequest(url)
|
||||
local function newWeather(x, y, day)
|
||||
local object = GUI.object(x, y, 14, 11)
|
||||
|
||||
if success then
|
||||
response = json:decode(response)
|
||||
if response.query and response.query.results and response.query.results.channel and response.query.results.channel.item and response.query.results.channel.item.condition and response.query.results.channel.item.condition.temp then
|
||||
return true, response
|
||||
else
|
||||
return false, "Ответ от Yahoo.com содержит неполную информацию, измените город или подождите некоторое время"
|
||||
end
|
||||
local type
|
||||
if day.weather[1].id == 800 then
|
||||
type = "sunny"
|
||||
elseif day.weather[1].id == 801 then
|
||||
type = "sunnyAndCloudy"
|
||||
elseif day.weather[1].id >= 800 then
|
||||
type = "cloudy"
|
||||
elseif day.weather[1].id >= 700 then
|
||||
type = "foggy"
|
||||
elseif day.weather[1].id >= 600 then
|
||||
type = "snowy"
|
||||
elseif day.weather[1].id >= 300 then
|
||||
type = "rainy"
|
||||
elseif day.weather[1].id >= 200 then
|
||||
type = "thundery"
|
||||
else
|
||||
return false, "Запрос погоды к Yahoo.com не удался. Повторите попытку."
|
||||
type = "sunnyAndCloudy"
|
||||
end
|
||||
end
|
||||
|
||||
--Конвертим ПЕНДОССКИЕ мили в километры
|
||||
local function convertMilesToKilometers(miles)
|
||||
return miles / 1.609344
|
||||
end
|
||||
|
||||
--Конвертируем МИЛИ В ЧАС, блядь, в МЕТРЫ В СЕКУНДУ
|
||||
local function convertMPHtoMS(mph)
|
||||
local kmph = convertMilesToKilometers(mph)
|
||||
local metersPerHour = 1000 * kmph
|
||||
local metersPerSecond = metersPerHour / 3600
|
||||
return metersPerSecond
|
||||
end
|
||||
|
||||
--Конвертируем давление в паскалях в царские ММ РТ СТОЛБА,Е ПТА
|
||||
local function converPascalsToMMHG(pascals)
|
||||
return pascals * 0.75006375541921
|
||||
end
|
||||
|
||||
--Ну, а тут фаренгейт точеный в цельсий дроченый
|
||||
local function convertFtoC(tempF)
|
||||
return ecs.adaptiveRound((tempF - 32) / 1.8)
|
||||
end
|
||||
|
||||
--А тут ебашим пиздатую иконку состояния погоды для прогноза (не охуевшую)
|
||||
local function drawCorrectWeatherIcon(x, y, weatherCode)
|
||||
buffer.image(x, y, image.load(weatherIcons[weatherCode] or pathsToWeatherTypes.sunny))
|
||||
end
|
||||
|
||||
--Конвертирует направление ветра в градусах от 0 до 360 в словесную интерпретацию ХУЙНИ
|
||||
local function getWindDirection(windAngle)
|
||||
local directions = {
|
||||
"северный",
|
||||
"северо-восточный",
|
||||
"восточный",
|
||||
"юго-восточный",
|
||||
"южный",
|
||||
"юго-западный",
|
||||
"западный",
|
||||
"северо-западный",
|
||||
local temp = math.round(day.temp.min) .. " / " .. math.round(day.temp.max) .. " °C"
|
||||
local pressure = math.round(day.pressure / 1.33322387415) .. " mm Hg"
|
||||
local humidity = math.round(day.humidity) .. "%"
|
||||
local winds = {
|
||||
[0] = "N",
|
||||
[1] = "NE",
|
||||
[2] = "E",
|
||||
[3] = "SE",
|
||||
[4] = "S",
|
||||
[5] = "SW",
|
||||
[6] = "W",
|
||||
[7] = "NW",
|
||||
[8] = "N",
|
||||
}
|
||||
local wind = day.speed .. " m/s, " .. (winds[math.round(day.deg / 45)] or "N/A")
|
||||
|
||||
local step = 360 / #directions * 2
|
||||
local currentDirection = 1
|
||||
|
||||
local windDirection = "N/A"
|
||||
|
||||
for i = 0, 360, step do
|
||||
if windAngle >= i and windAngle <= (i + step) then
|
||||
windDirection = directions[currentDirection]
|
||||
break
|
||||
end
|
||||
currentDirection = currentDirection + 1
|
||||
local function centerText(y, color, text)
|
||||
buffer.text(math.floor(object.x + object.width / 2 - unicode.len(text) / 2), y, color, text)
|
||||
end
|
||||
|
||||
return windDirection
|
||||
end
|
||||
|
||||
--Делаем массив погоды пиздатым, а не ебливо-пиндосским
|
||||
--Ну, там фаренгейты в цельсий, залупу в пизду и т.п.
|
||||
local function prepareJsonWeatherResponseFromDrawing(jsonWeatherResponse)
|
||||
weather.temperature = convertFtoC(jsonWeatherResponse.query.results.channel.item.condition.temp) .. "°"
|
||||
weather.pressure = "Давление: " .. ecs.adaptiveRound(converPascalsToMMHG(jsonWeatherResponse.query.results.channel.atmosphere.pressure)) .. " мм"
|
||||
weather.city = jsonWeatherResponse.query.results.channel.location.city .. ", " .. jsonWeatherResponse.query.results.channel.location.country
|
||||
weather.wind = "Ветер: " .. getWindDirection(tonumber(jsonWeatherResponse.query.results.channel.wind.direction)) .. ", " .. ecs.adaptiveRound(convertMPHtoMS(tonumber(jsonWeatherResponse.query.results.channel.wind.speed))) .. " м/с"
|
||||
weather.humidity = "Влажность: " .. jsonWeatherResponse.query.results.channel.atmosphere.humidity .. "%"
|
||||
|
||||
weather.forecast = {}
|
||||
for i = 1, #jsonWeatherResponse.query.results.channel.item.forecast do
|
||||
weather.forecast[i] = {}
|
||||
weather.forecast[i].day = jsonWeatherResponse.query.results.channel.item.forecast[i].day
|
||||
weather.forecast[i].code = tonumber(jsonWeatherResponse.query.results.channel.item.forecast[i].code)
|
||||
weather.forecast[i].temperature = convertFtoC(tonumber(jsonWeatherResponse.query.results.channel.item.forecast[i].high)) .. " / " .. convertFtoC(tonumber(jsonWeatherResponse.query.results.channel.item.forecast[i].low)).. "°"
|
||||
end
|
||||
end
|
||||
|
||||
local function drawWeather()
|
||||
--Рисуем обоинку или просто говнофон ССАНЫЙ
|
||||
if fs.exists(MineOSCore.properties.wallpaper or "---aefaefaefaefae") then
|
||||
buffer.image(1, 1, image.load(MineOSCore.properties.wallpaper))
|
||||
buffer.square(1, 1, buffer.getWidth(), buffer.getHeight(), 0x0, 0x0, " ", 0.6)
|
||||
else
|
||||
buffer.clear(0x262626)
|
||||
object.draw = function()
|
||||
centerText(object.y, 0xFFFFFF, os.date("%a", day.dt))
|
||||
buffer.image(object.x + 3, object.y + 2, weatherIcons[type])
|
||||
centerText(object.y + 7, 0xFFFFFF, temp)
|
||||
centerText(object.y + 8, 0xDDDDDD, wind)
|
||||
centerText(object.y + 9, 0xBBBBBB, pressure)
|
||||
centerText(object.y + 10, 0x999999, humidity)
|
||||
end
|
||||
|
||||
--Рисуем текущую температуру
|
||||
local x, y = 10, buffer.getHeight() - 25
|
||||
bigLetters.drawText(x, y, 0xFFFFFF, weather.temperature, drawWithSymbol)
|
||||
y = y + 6
|
||||
--Рисуем название города
|
||||
buffer.text(x, y, 0xFFFFFF, weather.city)
|
||||
--Рисуем ветер
|
||||
y = y + 2
|
||||
buffer.text(x, y, 0xFFFFFF, weather.wind)
|
||||
y = y + 1
|
||||
buffer.text(x, y, 0xFFFFFF, weather.pressure)
|
||||
y = y + 1
|
||||
buffer.text(x, y, 0xFFFFFF, weather.humidity)
|
||||
--Рисуем КНОПАЧКИ
|
||||
y = y + 2
|
||||
changeCityButton = {buffer.button(x, y, 22, 1, 0xEEEEEE, 0x262626, "Другой город")}
|
||||
exitButton = {buffer.button(buffer.getWidth() - 4, 2, 3, 1, 0xEEEEEE, 0x262626, "X")}
|
||||
|
||||
--Рисуем долгосрочный прогноз
|
||||
y = y + 3
|
||||
for i = 1, #weather.forecast do
|
||||
--Рисуем дату
|
||||
buffer.text(x + 2, y, 0xFFFFFF, weather.forecast[i].day)
|
||||
--Рисуем КОРТИНАЧКУ
|
||||
drawCorrectWeatherIcon(x, y + 2, weather.forecast[i].code)
|
||||
--Рисуем температуру
|
||||
buffer.text(x, y + 7, 0xFFFFFF, weather.forecast[i].temperature)
|
||||
x = x + 11
|
||||
end
|
||||
return object
|
||||
end
|
||||
|
||||
local function loadWeatherData()
|
||||
if fs.exists(pathToWeatherFile) then
|
||||
weather = table.fromFile(pathToWeatherFile)
|
||||
else
|
||||
weather = {
|
||||
myCity = "saint-petersburg",
|
||||
temperature = "0°",
|
||||
pressure = " ",
|
||||
city = "Получение информации о погоде...",
|
||||
wind = " ",
|
||||
humidity = " ",
|
||||
forecast = {},
|
||||
}
|
||||
end
|
||||
end
|
||||
local function updateForecast(city)
|
||||
local result, reason = web.request("http://api.openweathermap.org/data/2.5/forecast/daily?&appid=98ba4333281c6d0711ca78d2d0481c3d&units=metric&cnt=17&q=" .. web.encode(city))
|
||||
if result then
|
||||
result = json:decode(result)
|
||||
|
||||
if result.list then
|
||||
weatherContainer:deleteChildren()
|
||||
|
||||
local function saveWeatherData()
|
||||
table.toFile(pathToWeatherFile, weather)
|
||||
end
|
||||
|
||||
local function tryToGetAndDrawWeather()
|
||||
local success, jsonWeatherResponse = weatherRequest(weather.myCity)
|
||||
if success then
|
||||
--Подготавливаем данные под РУССКОЕ отображение ГОВНА
|
||||
prepareJsonWeatherResponseFromDrawing(jsonWeatherResponse)
|
||||
--РЕСУЕМ ПАГОДУ
|
||||
drawWeather()
|
||||
buffer.draw()
|
||||
--Сейвим погодку
|
||||
saveWeatherData()
|
||||
else
|
||||
GUI.error(jsonWeatherResponse)
|
||||
end
|
||||
end
|
||||
|
||||
local function clicked(x, y, object)
|
||||
if x >= object[1] and y >= object[2] and x <= object[3] and y <= object[4] then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
loadWeatherData()
|
||||
drawWeather()
|
||||
buffer.draw(true)
|
||||
|
||||
tryToGetAndDrawWeather()
|
||||
|
||||
while true do
|
||||
local e = {event.pull()}
|
||||
if e[1] == "touch" then
|
||||
if clicked(e[3], e[4], changeCityButton) then
|
||||
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
|
||||
{"EmptyLine"},
|
||||
{"CenterText", ecs.colors.orange, "Изменить город"},
|
||||
{"CenterText", ecs.colors.white, "(допускаются только названия по-английски)"},
|
||||
{"EmptyLine"},
|
||||
{"Input", 0xFFFFFF, ecs.colors.orange, weather.myCity},
|
||||
{"EmptyLine"},
|
||||
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
|
||||
)
|
||||
|
||||
if data[2] == "OK" then
|
||||
weather.myCity = data[1]
|
||||
tryToGetAndDrawWeather()
|
||||
local x, y = 1, 1
|
||||
local currentDay = result.list[1]
|
||||
local object = weatherContainer:addChild(GUI.object(x + 2, y, 40, 8))
|
||||
object.draw = function()
|
||||
bigLetters.drawText(object.x, object.y, 0xFFFFFF, math.round((currentDay.temp.max + currentDay.temp.min) / 2) .. "°")
|
||||
buffer.text(object.x, object.y + 6, 0xFFFFFF, result.city.name .. ", " .. result.city.country)
|
||||
buffer.text(object.x, object.y + 7, 0xFFFFFF, "Population: " .. math.shortenNumber(result.city.population, 2))
|
||||
end
|
||||
elseif clicked(e[3], e[4], exitButton) then
|
||||
-- buffer.clear(0x262626)
|
||||
-- ecs.prepareToExit()
|
||||
return
|
||||
|
||||
y = y + object.height + 1
|
||||
|
||||
local input = weatherContainer:addChild(GUI.input(x + 2, y, 25, 1, 0xE1E1E1, 0x666666, 0x666666, 0xE1E1E1, 0x2D2D2D, "", "Type city name here"))
|
||||
input.onInputFinished = function()
|
||||
updateForecast(input.text)
|
||||
input.text = ""
|
||||
|
||||
mainContainer:draw()
|
||||
buffer.draw()
|
||||
end
|
||||
|
||||
y = y + input.height + 2
|
||||
|
||||
for i = 1, #result.list do
|
||||
local object = weatherContainer:addChild(newWeather(x, y, result.list[i]))
|
||||
x = x + object.width + 2
|
||||
end
|
||||
else
|
||||
GUI.error(result.message)
|
||||
end
|
||||
else
|
||||
GUI.error("Wrong result. Check city name and try again.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
window.onResize = function(width, height)
|
||||
window.backgroundPanel.width = width
|
||||
window.backgroundPanel.height = height
|
||||
weatherContainer.width = width
|
||||
weatherContainer.localY = height - weatherContainer.height - 1
|
||||
weatherContainer.localX = 3
|
||||
end
|
||||
|
||||
window:resize(window.width, window.height)
|
||||
|
||||
updateForecast("Санкт-Петербург")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -770,7 +770,7 @@ function MineOSInterface.iconRightClick(icon, eventData)
|
||||
icon.parent.parent.launchers.showPackageContent(icon)
|
||||
end
|
||||
menu:addItem(MineOSCore.localization.launchWithArguments).onTouch = function()
|
||||
MineOSCore.launchWithArguments(MineOSInterface.mainContainer, icon.path)
|
||||
MineOSInterface.launchWithArguments(MineOSInterface.mainContainer, icon.path)
|
||||
end
|
||||
|
||||
menu:addSeparator()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user