add market place

This commit is contained in:
Xuan Sang LE 2020-05-19 01:03:49 +02:00
parent d1e8fd91dc
commit ff6f480f08
14 changed files with 353 additions and 216 deletions

View File

@ -49,10 +49,7 @@ coffees= src/core/core.coffee \
src/core/tags/SystemPanelTag.coffee \ src/core/tags/SystemPanelTag.coffee \
src/antos.coffee src/antos.coffee
packages = CoreServices Files Setting CodePad MarketPlace
packages = CoreServices Files Setting CodePad
main: initd build_coffees build_themes libs build_packages languages main: initd build_coffees build_themes libs build_packages languages
- cp src/index.html $(BUILDDIR)/ - cp src/index.html $(BUILDDIR)/

View File

@ -290,7 +290,7 @@ SelectionDialog.scheme = """
<afx-hbox data-height="30"> <afx-hbox data-height="30">
<div /> <div />
<afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" /> <afx-button data-id = "btnOk" text = "__(Ok)" data-width = "40" />
<afx-button data-id = "btnCancel" text = "__(Cancels)" data-width = "50" /> <afx-button data-id = "btnCancel" text = "__(Cancel)" data-width = "50" />
</afx-hbox> </afx-hbox>
</afx-vbox> </afx-vbox>
<div data-width = "10" /> <div data-width = "10" />

View File

@ -208,11 +208,11 @@ Ant.OS.API =
r.responseType = "arraybuffer" r.responseType = "arraybuffer"
r.onload = (e) -> r.onload = (e) ->
if @status is 200 and @readyState is 4 if @status is 200 and @readyState is 4
resolve @response
Ant.OS.API.loaded q, p, "OK" Ant.OS.API.loaded q, p, "OK"
resolve @response
else else
reject e, @
Ant.OS.API.loaded q, p, "FAIL" Ant.OS.API.loaded q, p, "FAIL"
reject Ant.OS.API.throwe __("Unable to get blob: {0}", p)
Ant.OS.API.loading q, p Ant.OS.API.loading q, p
r.send() r.send()

View File

@ -1,7 +1,7 @@
{ {
"app":"{0}", "app":"{0}",
"name":"{0}", "name":"{0}",
"description":"", "description":"{0}",
"info":{ "info":{
"author": "", "author": "",
"email": "" "email": ""

View File

@ -16,78 +16,67 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #along with this program. If not, see https://www.gnu.org/licenses/.
class RepositoryDialog extends this.OS.GUI.BaseDialog class RepositoryDialog extends this.OS.GUI.subwindows.SelectionDialog
constructor: () -> constructor: () ->
super "RepositoryDialog" super()
init: () ->
@_gui.htmlToScheme RepositoryDialog.scheme, @, @host
#@render "#{@meta().path}/repositorydia.html"
main: () -> main: () ->
me = @ @list = @find "list"
@list = @find "repo-list" $((@find "btnOk")).hide()
@list.set "onlistdbclick", (e) ->
selidx = me.list.get "selidx"
return unless selidx >= 0
sel = me.systemsetting.system.repositories[selidx]
me.openDialog "PromptDialog", (e) ->
m = e.match /\[([^\]]*)\]\s*(.*)/
return me.error "Wrong format: it should be [name] url" if not m or m.length isnt 3
sel.name = m[1]
sel.text = sel.name
sel.url = m[2]
me.refreshList()
, __("Edit repository"), { label: __("Format : [name] url"), value: "[#{e.data.text}] #{e.data.url}" }
@list.set "buttons", [ @list.set "buttons", [
{ {
text: "+", text: "+",
onbtclick: () -> onbtclick: () =>
me.openDialog "PromptDialog", (e) -> @openDialog("PromptDialog", {
m = e.match /\[([^\]]*)\]\s*(.*)/ title: __("Add repository"),
return me.error __("Wrong format: it should be [name] url") if not m or m.length isnt 3 label: __("Format : [name] url")
me.systemsetting.system.repositories.push { }).then (e) =>
name: m[1], m = e.match /\[([^\]]*)\]\s*(.+)/
if not m or m.length isnt 3
return @error __("Wrong format: it should be [name] url")
repo = {
url: m[2], url: m[2],
text: m[1], text: m[1]
i: me.systemsetting.system.repositories.length
} }
me.refreshList() @systemsetting.system.repositories.push repo
, __("Add repository"), { label: __("Format : [name] url") } @list.push repo
}, },
{ {
text: "-", text: "-",
onbtclick: () -> onbtclick: () =>
selidx = me.list.get "selidx" el = @list.get "selectedItem"
return unless el
selidx = $(el).index()
return unless selidx >= 0 return unless selidx >= 0
me.systemsetting.system.repositories.splice selidx, selidx @systemsetting.system.repositories.splice selidx, selidx
me.refreshList() @list.remove el
},
{
iconclass: "fa fa-pencil",
onbtclick: () => @editRepo()
} }
] ]
(@find "btquit").set "onbtclick", (e) -> me.quit() editRepo: () ->
@refreshList() el = @list.get "selectedItem"
refreshList: () -> return unless el
ls = ({ selidx = $(el).index()
text: v.name, return unless selidx >= 0
iconclass: "fa fa-link", data = el.get "data"
url: v.url, sel = @systemsetting.system.repositories[selidx]
complex: true, @openDialog("PromptDialog", {
detail: [{ text: v.url }] title: __("Edit repository"),
} for v in @systemsetting.system.repositories) label: __("Format : [name] url"),
@list.set "items", ls value: "[#{data.text}] #{data.url}"
}).then (e) =>
m = e.match /\[([^\]]*)\]\s*(.+)/
if not m or m.length isnt 3
return @error __("Wrong format: it should be [name] url")
data.text = m[1]
data.url = m[2]
@list.update()
@list.unselect()
onexit: (e) -> onexit: (e) ->
@parent.repo.set "items", @systemsetting.system.repositories @parent.refreshRepoList()
@parent.dialog = undefined if @parent super.onexit e
RepositoryDialog.scheme = """
<afx-app-window data-id = "repository-dialog-win" apptitle="__(Repositories)" width="250" height="250">
<afx-vbox >
<afx-list-view data-id="repo-list"></afx-list-view>
<div style = "text-align:right; padding:5px" data-height="30" >
<afx-button data-id = "btquit" text = "__(Cancel)"></afx-button>
</div>
</afx-vbox>
</afx-app-window>
"""

View File

@ -16,25 +16,27 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/. #along with this program. If not, see https://www.gnu.org/licenses/.
self = this
class MarketPlace extends this.OS.GUI.BaseApplication class MarketPlace extends this.OS.GUI.BaseApplication
constructor: (args) -> constructor: (args) ->
super "MarketPlace", args super "MarketPlace", args
main: () -> main: () ->
me = @
@installdir = @systemsetting.system.pkgpaths.user @installdir = @systemsetting.system.pkgpaths.user
# test repository # test repository
@apps_meta = []
@repo = @find "repo" @repo = @find "repo"
@repo.set "onlistselect", (e) -> @repo.set "onlistselect", (e) =>
return unless e.data data = e.data.item.get("data")
me.fetchApps e.data.url return unless data
@repo.set "items", @systemsetting.system.repositories @fetchApps data
@refreshRepoList()
@applist = @find "applist" @applist = @find "applist"
@applist.set "onlistselect", (e) -> @applist.set "onlistselect", (e) =>
return unless e.data data = e.data.item.get("data")
me.appDetail e.data @appDetail data
@container = @find "container" @container = @find "container"
@appname = @find "appname" @appname = @find "appname"
@appdesc = @find "app-desc" @appdesc = @find "app-desc"
@ -42,39 +44,105 @@ class MarketPlace extends this.OS.GUI.BaseApplication
@btinstall = @find "bt-install" @btinstall = @find "bt-install"
@btremove = @find "bt-remove" @btremove = @find "bt-remove"
@btexec = @find "bt-exec" @btexec = @find "bt-exec"
($ @container ).css "visibility", "hidden" @searchbox = @find "searchbox"
@btexec.set "onbtclick", (e) -> ($ @container).css "visibility", "hidden"
app = me.applist.get "selected" @btexec.set "onbtclick", (e) =>
return unless app el = @applist.get "selectedItem"
me._gui.launch app.className if app.className return unless el
@btinstall.set "onbtclick", (e) -> app = el.get("data")
return me.update() if me.btinstall.get "dirty" @_gui.launch app.className if app.className
me.install()
@btremove.set "onbtclick", (e) -> @btinstall.set "onbtclick", (e) =>
me.uninstall() if @btinstall.get "dirty"
@bindKey "CTRL-R", () -> return @update()
me.openDialog new RepositoryDialog() .then () => @notify __("Package updated")
fetchApps: (url) -> .catch (e) => @error e.toString(), e
me = @ @remoteInstall()
@_api.get url, ( d ) -> .then () => @notify __("Package installed")
for v in d .catch (e) => @error e.toString(), e
v.text = v.name
v.iconclass = "fa fa-adn" @btremove.set "onbtclick", (e) =>
me.applist.set "items", d @uninstall()
, (e, s) -> .then () => @notify __("Packaged uninstalled")
me.error __("Fail to fetch packages list from: {0}", url) .catch (e) => @error e.toString(), e
@bindKey "CTRL-R", () =>
@menuOptionsHandle "repos"
$(@searchbox).keyup (e) => @search e
refreshRepoList: () ->
list = (v for v in @systemsetting.system.repositories)
list.unshift {
text: "Installed"
}
@repo.set "data", list
search: (e) ->
switch e.which
when 37
e.preventDefault()
when 38
@applist.selectPrev()
e.preventDefault()
when 39
e.preventDefault()
when 40
@applist.selectNext()
e.preventDefault()
when 13
e.preventDefault()
else
text = @searchbox.value
@applist.set "data", (v for v in @apps_meta) if text.length is 2
return if text.length < 3
result = []
term = new RegExp text, 'i'
result.push v for v in @apps_meta when v.text.match term
@applist.set "data", result
fetchApps: (data) ->
if not data.url
pkgcache = @systemsetting.system.packages
list = []
for k, v of pkgcache
list.push {
className: v.app,
name: v.name,
text: v.name,
icon: v.icon,
iconclass: v.iconclass,
category: v.category,
author: v.info.author,
version: v.version,
description: "#{v.path}/REAME.md"
}
@apps_meta = list
@applist.set "data", list
return
@_api.get data.url
.then ( d ) =>
for v in d
v.text = v.name
v.iconclass = "fa fa-adn"
@apps_meta = d
@applist.set "data", d
.catch (e) ->
@error __("Fail to fetch packages list from: {0}", data.url), e
appDetail: (d) -> appDetail: (d) ->
me = @
($ @container).css "visibility", "visible" ($ @container).css "visibility", "visible"
( $ @appname ).html d.name ( $ @appname ).html d.name
(@find "vstat").set "text", "" (@find "vstat").set "text", ""
if d.description if d.description
d.description.asFileHandler().read (text) -> d.description.asFileHandle().read().then (text) =>
converter = new showdown.Converter() converter = new showdown.Converter()
($ me.appdesc).html converter.makeHtml text ($ @appdesc).html(converter.makeHtml text)
.catch (e) => @notify __("Unable to read package description")
else else
($ me.appdesc).empty() ($ @appdesc).empty()
pkgcache = @systemsetting.system.packages pkgcache = @systemsetting.system.packages
@btinstall.set "text", "__(Install)" @btinstall.set "text", "__(Install)"
@btinstall.set "dirty", false @btinstall.set "dirty", false
@ -89,7 +157,8 @@ class MarketPlace extends this.OS.GUI.BaseApplication
@btinstall.set "dirty", true @btinstall.set "dirty", true
@btinstall.set "text", "__(Update)" @btinstall.set "text", "__(Update)"
($ @btinstall).show() ($ @btinstall).show()
(@find "vstat").set "text", __("Your application version is older ({0} < {1})", vs, ovs) (@find "vstat").set "text",
__("Your application version is older ({0} < {1})", vs, ovs)
($ @btremove).show() ($ @btremove).show()
($ @btexec).show() ($ @btexec).show()
else else
@ -98,111 +167,185 @@ class MarketPlace extends this.OS.GUI.BaseApplication
($ @btexec).hide() ($ @btexec).hide()
($ @appdetail).empty() ($ @appdetail).empty()
for k, v of d when k isnt "name" and k isnt "description" for k, v of d when k isnt "name" and k isnt "description" and k isnt "domel"
($ @appdetail).append $("<li>").append(($ "<span class= 'info-header'>").html k).append $("<span>").html v ($ @appdetail).append(
$("<li>")
.append(($ "<span class= 'info-header'>").html k)
.append $("<span>").html v
)
menu: () -> menu: () ->
me = @
return [ return [
{ text: "__(Options)", child: [ {
{ text: "__(Repositories)", shortcut: "C-R" } text: "__(Options)", child: [
] , onmenuselect: (e) -> { text: "__(Repositories)", shortcut: "C-R", id: "repos" },
me.openDialog new RepositoryDialog() { text: "__(Install from zip)", shortcut: "C-I", id: "install" }
] , onchildselect: (e) =>
@menuOptionsHandle e.data.item.get("data").id
} }
] ]
install: (f) -> menuOptionsHandle: (id) ->
me = @ switch id
app = @applist.get "selected" when "repos"
@openDialog new RepositoryDialog(), {
title: __("Repositories"),
data: @systemsetting.system.repositories
}
when "install"
@localInstall().then () =>
@notify __("Package installed")
.catch (e) => @error __("Unable to install package"), e
else
remoteInstall: () ->
el = @applist.get "selectedItem"
return unless el
app = el.get "data"
return unless app return unless app
# get blob file # get blob file
@_api.blob app.download, (data) -> new Promise (resolve, reject) =>
JSZip.loadAsync(data).then (zip) -> @_api.blob app.download
pth = "#{me.installdir}/#{app.className}" .then (data) =>
dir = [pth] @install data, app
files = [] .then () -> resolve()
for name, file of zip.files .catch (e) -> reject(e)
if file.dir .catch (e) -> reject e
dir.push(pth + "/" + name)
else localInstall: () ->
files.push name new Promise (resolve, reject) =>
idx = files.indexOf "package.json" @openDialog("FileDialog", {
return me.error __("Invalid package: Meta data file not found") if idx < 0 title: "__(Select package archive)",
# create all directory mimes: [".*/zip"]
me.mkdirs app.className, dir, () -> }).then (d) =>
me.installFile app.className, zip, files, () -> d.file.path.asFileHandle().read("binary").then (data) =>
zip.file("package.json").async("string").then (d) -> @install data
v = JSON.parse d .then (n) =>
@repo.unselect()
@repo.set "selected", 0
apps = (v.className for v in @applist.get("data"))
idx = apps.indexOf n
if idx >= 0
@applist.set "selected", idx
resolve()
.catch (e) -> reject(e)
.catch (e) -> reject e
.catch (e) -> reject e
install: (data, meta) ->
new Promise (resolve, reject) =>
JSZip.loadAsync(data).then (zip) =>
zip.file("package.json").async("string").then (d) =>
v = JSON.parse d
pth = "#{@installdir}/#{v.app}"
dir = [pth]
files = []
for name, file of zip.files
if file.dir
dir.push(pth + "/" + name)
else
files.push name
# create all directory
@mkdirs(dir).then () =>
@installFile(v.app, zip, files).then () =>
app_meta = {
className: v.app,
name: v.name,
text: v.name,
icon: v.icon,
iconclass: v.iconclass,
category: v.category,
author: v.info.author,
version: v.version,
description: if meta then meta.description else undefined,
download: if meta then meta.download else undefined
}
v.text = v.name v.text = v.name
v.filename = app.className v.filename = v.app
v.type = "app" v.type = "app"
v.mime = "antos/app" v.mime = "antos/app"
v.iconclass = "fa fa-adn" unless v.iconclass or v.icon v.iconclass = "fa fa-adn" unless v.iconclass or v.icon
v.path = pth v.path = pth
me.systemsetting.system.packages[app.className] = v @systemsetting.system.packages[v.app] = v
me.notify __("Application installed") @notify __("Application installed")
me._gui.refreshSystemMenu() @appDetail app_meta
me.appDetail app resolve(v.name)
.catch (err) -> .catch (e) -> reject e
me.error __("Error reading package meta data: {0}", err) .catch (e) -> reject e
.catch (err) -> reject err
.catch (e) -> reject e
, (err, s) -> uninstall: () ->
return me.error __("Cannot down load the app {0}", err) if err new Promise (resolve, reject) =>
uninstall: (f) -> el = @applist.get "selectedItem"
me = @ return unless el
sel = @applist.get "selected" sel = el.get "data"
name = sel.className return unless sel
return unless sel name = sel.className
app = @systemsetting.system.packages[sel.className] app = @systemsetting.system.packages[sel.className]
return unless app return unless app
@openDialog "YesNoDialog", @openDialog("YesNoDialog", {
(d) -> title: __("Uninstall") ,
text: __("Uninstall: {0}?", app.name)
}).then (d) =>
return unless d return unless d
app.path.asFileHandler().remove (r) -> app.path.asFileHandle().remove().then (r) =>
return me.error __("Cannot uninstall package: {0}", r.error) if r.error if r.error
me.notify __("Package uninstalled") return reject @_api.throwe __("Cannot uninstall package: {0}", r.error)
delete me.systemsetting.system.packages[name] @notify __("Package uninstalled")
me._gui.unloadApp name delete @systemsetting.system.packages[name]
me._gui.refreshSystemMenu() @_gui.unloadApp name
me.appDetail sel if sel.download
f() if f @appDetail sel
, __("Uninstall") , else
{ text: __("Uninstall: {0}?", app.name) } @applist.remove el
($ @container).css "visibility", "hidden"
resolve()
.catch (e) -> reject e
.catch (e) -> reject e
update: () -> update: () ->
me = @ new Promise (resolve, reject) =>
new Promise (r, e) -> @uninstall().then () =>
me.uninstall () -> @remoteInstall()
r() .then () -> resolve()
.then () -> .catch (e) -> reject e
me.install() .catch (e) -> reject e
mkdirs: (n, list, f) -> mkdirs: (list) ->
me = @ new Promise (resolve, reject) =>
if list.length is 0 return resolve() if list.length is 0
f() if f dir = (list.splice 0, 1)[0].asFileHandle()
return path = dir.parent()
dir = (list.splice 0, 1)[0].asFileHandler() dname = dir.basename
path = dir.parent() path.asFileHandle().mk dname
dname = dir.basename .then (r) =>
path.asFileHandler().mk dname, (r) -> return reject(@_api.throwe __("Cannot create {0}", "#{path}/#{dir}")) if r.error
return me.mkdirs n, list, f if r.result @mkdirs list
me.error __("Cannot create {0}", "#{path}/#{dir}") .then () -> resolve()
.catch (e) -> reject e
.catch (e) -> reject e
installFile: (n, zip, files, f) -> installFile: (n, zip, files) ->
me = @ new Promise (resolve, reject) =>
if files.length is 0 return resolve() if files.length is 0
f() if f file = (files.splice 0, 1)[0]
return path = "#{@installdir}/#{n}/#{file}"
file = (files.splice 0, 1)[0] zip.file(file).async("uint8array").then (d) =>
path = "#{me.installdir}/#{n}/#{file}" fp = path.asFileHandle()
zip.file(file).async("uint8array").then (d) -> fp.cache = new Blob [d], { type: "octet/stream" }
fp = path.asFileHandler() fp.write "text/plain"
fp.cache = new Blob [d], { type: "octet/stream" } .then (r) =>
fp.write "text/plain", (r) -> return reject @_api.throwe(__("Cannot install {0}", path)) if r.error
return me.installFile n, zip, files, f if r.result @installFile n, zip, files
me.error __("Cannot install {0}", path) .then () -> resolve()
.catch (e) -> reject()
.catch (e) -> reject e
.catch (e) -> reject e
MarketPlace.dependencies = [ "jszip.min", "showdown.min" ] MarketPlace.dependencies = [
"os://scripts/jszip.min.js",
"os://scripts/showdown.min.js"
]
MarketPlace.singleton = true MarketPlace.singleton = true
this.OS.register "MarketPlace", MarketPlace this.OS.register "MarketPlace", MarketPlace

View File

@ -1,17 +1,9 @@
afx-app-window[data-id ='marketplace-win'] afx-resizer{
background-color: transparent;
border-left: 1px solid #cbcbcb;
}
afx-app-window[data-id ='marketplace-win'] afx-list-view[data-id='applist']{
background-color: #f6F6F6;
padding:0;
}
afx-app-window[data-id="marketplace-win"] afx-list-view[data-id='repo'] div.list-container{ afx-app-window[data-id="marketplace-win"] afx-list-view[data-id='repo'] div.list-container{
z-index: 10; z-index: 10;
} }
afx-app-window[data-id="marketplace-win"] afx-vbox[data-id='container'] { afx-app-window[data-id="marketplace-win"] afx-vbox[data-id='container'] {
color: #414339;
overflow-y: auto; overflow-y: auto;
} }
afx-app-window[data-id="marketplace-win"] afx-vbox[data-id='container'] afx-hbox { afx-app-window[data-id="marketplace-win"] afx-vbox[data-id='container'] afx-hbox {
@ -21,7 +13,6 @@ afx-app-window[data-id="marketplace-win"] div[data-id='appname'] {
font-weight: bold; font-weight: bold;
font-size: 20px; font-size: 20px;
padding: 10px; padding: 10px;
color: #414339;
} }
afx-app-window[data-id="marketplace-win"] div[data-id='appname']:before { afx-app-window[data-id="marketplace-win"] div[data-id='appname']:before {
@ -30,7 +21,6 @@ afx-app-window[data-id="marketplace-win"] div[data-id='appname']:before {
font-size: 25px; font-size: 25px;
font-style: normal; font-style: normal;
margin-right: 10px; margin-right: 10px;
color: #414339;
} }
afx-app-window[data-id="marketplace-win"] p[data-id='app-desc'] { afx-app-window[data-id="marketplace-win"] p[data-id='app-desc'] {
text-align: justify; text-align: justify;
@ -47,6 +37,23 @@ afx-app-window[data-id="marketplace-win"] ul[data-id='app-detail'] {
display: table; display: table;
margin: 0; margin: 0;
} }
afx-app-window[data-id="marketplace-win"] afx-hbox[data-id="search-container"] {
border-bottom: 1px solid #afafaf;
}
afx-app-window[data-id="marketplace-win"] afx-hbox[data-id="search-container"] input{
border: 0;
background-color: transparent;
}
afx-app-window[data-id="marketplace-win"] div[data-id="searchicon"]:before{
content: "\f002";
display: block;
background-color:transparent;
color:#afafaf;
font-family: "FontAwesome";
padding-top: 3px;
padding-left:3px;
/* font-size: 25px; */
}
afx-app-window[data-id="marketplace-win"] ul[data-id='app-detail'] li{ afx-app-window[data-id="marketplace-win"] ul[data-id='app-detail'] li{
padding:0; padding:0;
margin: 0; margin: 0;

View File

@ -1,7 +1,7 @@
{ {
"app":"MarketPlace", "app":"MarketPlace",
"name":"Application store", "name":"Application store",
"description":"Application store and repository management", "description":"Application store",
"info":{ "info":{
"author": "Xuan Sang LE", "author": "Xuan Sang LE",
"email": "xsang.le@gmail.com" "email": "xsang.le@gmail.com"
@ -9,5 +9,6 @@
"version":"0.0.1-a", "version":"0.0.1-a",
"category":"System", "category":"System",
"iconclass":"fa fa-adn", "iconclass":"fa fa-adn",
"mimes":["none"] "mimes":["none"],
"locales": {}
} }

View File

@ -1,13 +1,17 @@
<afx-app-window data-id = "marketplace-win" apptitle="MarketPlace" width="500" height="400"> <afx-app-window data-id = "marketplace-win" apptitle="MarketPlace" width="500" height="400">
<afx-hbox > <afx-hbox >
<afx-vbox data-width = "172" data-id = "sidebar" min-width="172"> <afx-vbox data-width = "172" data-id = "sidebar" min-width="172">
<afx-list-view data-id = "repo" dropdown = "true" data-height= "30" width = "150"></afx-list-view> <afx-list-view data-id = "repo" dropdown = "true" data-height= "25" width = "150"></afx-list-view>
<afx-hbox data-height= "23" data-id="search-container">
<div data-width="17" data-id="searchicon"></div>
<input data-id = "searchbox" />
</afx-hbox>
<afx-list-view data-id = "applist" dropdown = "false" width = "150"></afx-list-view> <afx-list-view data-id = "applist" dropdown = "false" width = "150"></afx-list-view>
</afx-vbox> </afx-vbox>
<afx-resizer data-width = "3" ></afx-resizer> <afx-resizer data-width = "3" ></afx-resizer>
<afx-vbox data-id = "container"> <afx-vbox data-id = "container">
<div data-id = "appname" data-height = "25"></div> <div data-id = "appname" data-height = "25"></div>
<afx-hbox data-height = "grow"> <afx-hbox data-height = "30">
<div style = "text-align:left;"> <div style = "text-align:left;">
<afx-button data-id = "bt-remove" text = "__(Uninstall)"></afx-button> <afx-button data-id = "bt-remove" text = "__(Uninstall)"></afx-button>
<afx-button data-id = "bt-exec" text = "__(Launch)"></afx-button> <afx-button data-id = "bt-exec" text = "__(Launch)"></afx-button>

View File

@ -102,14 +102,12 @@ afx-file-view afx-tree-view .afx-tree-view-item:before{
content: "\f016"; content: "\f016";
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 16px; font-size: 16px;
color: #414339;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
} }
afx-file-view afx-tree-view div.afx_tree_item_selected, afx-file-view afx-tree-view div.afx_tree_item_selected:hover{ afx-file-view afx-tree-view div.afx_tree_item_selected, afx-file-view afx-tree-view div.afx_tree_item_selected:hover{
background-color: transparent; background-color: transparent;
color:#414339;
} }
afx-file-view afx-tree-view li.itemname{ afx-file-view afx-tree-view li.itemname{

View File

@ -29,7 +29,7 @@ afx-list-view > div.list-container > ul > afx-list-item > li.selected{
} }
afx-list-view.dropdown > div.list-container > ul{ afx-list-view.dropdown > div.list-container > ul{
border:1px solid #a6a6a6; border:1px solid #262626;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65); box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border-radius: 3px; border-radius: 3px;
max-height: 150px; max-height: 150px;
@ -42,7 +42,7 @@ afx-list-view.dropdown div.list-container div{
color: white; color: white;
padding-top:3px; padding-top:3px;
padding-bottom: 3px; padding-bottom: 3px;
border:1px solid #a6a6a6; border:1px solid #262626;
border-radius: 3px; border-radius: 3px;
background-color: transparent; background-color: transparent;
height: 17px; height: 17px;
@ -55,14 +55,12 @@ afx-list-view.dropdown div.list-container div:before {
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 11px; font-size: 11px;
font-style: normal; font-style: normal;
color: #414339;
position: absolute; position: absolute;
top:25%; top:25%;
right: 5px; right: 5px;
} }
afx-list-view.dropdown > div.list-container > ul li:hover{ afx-list-view.dropdown > div.list-container > ul li:hover{
background-color: #dcdcdc; background-color: #464646;
color: #414339;
} }
afx-list-view ul.complex-content{ afx-list-view ul.complex-content{
padding: 0; padding: 0;

View File

@ -1,3 +1,4 @@
afx-resizer { afx-resizer {
background-color: #868686; background-color: transparent;
border-left: 1px solid #262626;
} }

View File

@ -101,14 +101,12 @@ afx-file-view afx-tree-view .afx-tree-view-item:before{
content: "\f016"; content: "\f016";
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 16px; font-size: 16px;
color: #414339;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
} }
afx-file-view afx-tree-view div.afx_tree_item_selected, afx-file-view afx-tree-view div.afx_tree_item_selected:hover{ afx-file-view afx-tree-view div.afx_tree_item_selected, afx-file-view afx-tree-view div.afx_tree_item_selected:hover{
background-color: transparent; background-color: transparent;
color:#414339;
} }
afx-file-view afx-tree-view li.itemname{ afx-file-view afx-tree-view li.itemname{

View File

@ -1,3 +1,4 @@
afx-resizer { afx-resizer {
background-color: #cbcbcb; background-color: transparent;
border-left: 1px solid #868686;
} }