Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
mycard
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
syntax_j
mycard
Commits
d97349d0
Commit
d97349d0
authored
Nov 06, 2016
by
神楽坂玲奈
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'v3' of github.com:mycard/mycard into v3
parents
69513b55
f81a7ac0
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
162 additions
and
170 deletions
+162
-170
app/app-detail.component.html
app/app-detail.component.html
+4
-3
app/app-detail.component.ts
app/app-detail.component.ts
+5
-58
app/app.ts
app/app.ts
+1
-1
app/apps.service.ts
app/apps.service.ts
+97
-101
app/install.service.ts
app/install.service.ts
+54
-6
app/mycard.component.html
app/mycard.component.html
+1
-1
No files found.
app/app-detail.component.html
View file @
d97349d0
...
...
@@ -12,7 +12,7 @@
class=
"progress progress-striped progress-animated"
value=
"{{currentApp.status.progress}}"
max=
"{{currentApp.status.total}}"
></progress>
<div
*ngIf=
"currentApp.status.status==='ready' && (currentApp.id != 'ygopro')"
>
<button
(click)=
"
start
App(currentApp)"
type=
"button"
class=
"btn btn-primary"
>
运行
</button>
<button
(click)=
"
run
App(currentApp)"
type=
"button"
class=
"btn btn-primary"
>
运行
</button>
<button
type=
"button"
data-toggle=
"modal"
data-target=
"#settings-modal"
class=
"btn btn-secondary"
>
设置
</button>
<!--<button (click)="appsService.browse(currentApp)" type="button" class="btn btn-secondary">游览本地文件</button>-->
...
...
@@ -114,7 +114,7 @@
<div
*ngIf=
"currentApp.isInstalled()"
>
<h2>
本地文件
</h2>
<button
(click)=
"appsService.browse(currentApp)"
type=
"button"
class=
"btn btn-secondary"
>
浏览本地文件
</button>
<button
(click)=
"uninstall(currentApp
.id
)"
type=
"button"
class=
"btn btn-secondary"
>
<button
(click)=
"uninstall(currentApp)"
type=
"button"
class=
"btn btn-secondary"
>
{{'uninstall'|translate}}
</button>
</div>
...
...
@@ -202,7 +202,8 @@
<h4>
{{'additions'|translate}}
</h4>
<div
*ngFor=
"let reference of installConfig.references"
>
<label>
<input
type=
"checkbox"
[(ngModel)]=
"reference.install"
name=
"references"
value=
"{{reference.app.id}}"
>
<input
type=
"checkbox"
[(ngModel)]=
"reference.install"
name=
"references"
value=
"{{reference.app.id}}"
>
{{reference.app.name}}
</label>
</div>
...
...
app/app-detail.component.ts
View file @
d97349d0
...
...
@@ -30,11 +30,6 @@ export class AppDetailComponent implements OnInit {
}
ngOnInit
()
{
// this.updateInstallConfig();
ipcRenderer
.
on
(
'
download-message-reply
'
,
(
event
,
arg
)
=>
{
console
.
log
(
arg
);
});
ipcRenderer
.
send
(
"
download-message
"
,
"
ping
"
)
}
updateInstallConfig
()
{
...
...
@@ -54,14 +49,6 @@ export class AppDetailComponent implements OnInit {
return
this
.
currentApp
.
news
;
}
get
friends
()
{
return
false
;
}
get
achievement
()
{
return
false
;
}
get
mods
()
{
// let contains = ["optional", "language", "emulator"];
//
...
...
@@ -95,15 +82,11 @@ export class AppDetailComponent implements OnInit {
return
[];
}
uninstalling
:
boolean
;
uninstall
(
id
:
string
)
{
async
uninstall
(
app
:
App
)
{
if
(
confirm
(
"
确认删除?
"
))
{
this
.
uninstalling
=
true
;
// this.appsService.uninstall(id).then(()=> {
// this.uninstalling = false;
// }
// );
await
this
.
installService
.
uninstall
(
app
);
this
.
currentApp
.
status
.
status
=
"
init
"
;
}
}
...
...
@@ -148,9 +131,7 @@ export class AppDetailComponent implements OnInit {
return
this
.
installService
.
add
(
completeApp
,
options
);
});
}));
console
.
log
(
"
before
"
)
await
this
.
installService
.
getComplete
(
currentApp
);
console
.
log
(
"
install complete
"
);
currentApp
.
status
.
status
=
"
ready
"
;
this
.
ref
.
detectChanges
();
}
catch
(
e
)
{
...
...
@@ -167,42 +148,8 @@ export class AppDetailComponent implements OnInit {
return
dir
[
0
];
}
startApp
(
app
:
App
)
{
let
execute
=
path
.
join
(
app
.
local
.
path
,
app
.
actions
.
get
(
"
main
"
).
execute
);
let
args
=
app
.
actions
.
get
(
"
main
"
).
args
;
let
env
=
app
.
actions
.
get
(
"
main
"
).
env
;
let
opt
=
{
cwd
:
app
.
local
.
path
,
env
:
env
};
let
open
=
''
;
let
openApp
=
app
.
actions
.
get
(
"
main
"
).
open
;
if
(
openApp
)
{
open
=
path
.
join
(
openApp
.
local
.
path
,
openApp
.
actions
.
get
(
"
main
"
).
execute
);
args
.
push
(
execute
);
}
else
{
//没有需要通过open启动依赖,直接启动程序
open
=
execute
;
}
let
handle
=
child_process
.
spawn
(
open
,
args
,
opt
);
handle
.
stdout
.
on
(
'
data
'
,
(
data
)
=>
{
console
.
log
(
`stdout:
${
data
}
`
);
});
handle
.
stderr
.
on
(
'
data
'
,
(
data
)
=>
{
console
.
log
(
`stderr:
${
data
}
`
);
});
handle
.
on
(
'
close
'
,
(
code
)
=>
{
console
.
log
(
`child process exited with code
${
code
}
`
);
remote
.
getCurrentWindow
().
restore
();
});
remote
.
getCurrentWindow
().
minimize
();
runApp
(
app
:
App
)
{
this
.
appsService
.
runApp
(
app
);
}
copy
(
text
)
{
...
...
app/app.ts
View file @
d97349d0
...
...
@@ -55,7 +55,7 @@ export class App {
status
:
AppStatus
;
isInstalled
():
boolean
{
return
this
.
local
!==
undefined
;
return
!!
this
.
local
;
}
constructor
(
app
)
{
...
...
app/apps.service.ts
View file @
d97349d0
import
{
Injectable
,
ApplicationRef
,
NgZone
}
from
"
@angular/core
"
;
import
{
Injectable
,
ApplicationRef
}
from
"
@angular/core
"
;
import
{
Http
}
from
"
@angular/http
"
;
import
{
App
,
AppStatus
}
from
"
./app
"
;
import
{
InstallConfig
}
from
"
./install-config
"
;
...
...
@@ -17,24 +17,27 @@ import {AppLocal} from "./app-local";
const
Aria2
=
require
(
'
aria2
'
);
const
Sudo
=
require
(
'
electron-sudo
'
).
default
;
Sudo
.
prototype
.
fork
=
async
function
(
modulePath
,
args
,
options
)
{
let
child
=
await
this
.
spawn
(
remote
.
app
.
getPath
(
'
exe
'
),
[
'
-e
'
,
modulePath
].
concat
(
args
),
options
);
readline
.
createInterface
({
input
:
child
.
stdout
}).
on
(
'
line
'
,
(
line
)
=>
{
child
.
emit
(
'
message
'
,
JSON
.
parse
(
line
));
});
child
.
send
=
(
message
,
sendHandle
,
options
,
callback
)
=>
{
child
.
stdin
.
write
(
JSON
.
stringify
(
message
)
+
os
.
EOL
);
if
(
callback
)
{
callback
()
}
};
return
child
Sudo
.
prototype
.
fork
=
function
(
modulePath
,
args
,
options
)
{
return
this
.
spawn
(
remote
.
app
.
getPath
(
'
exe
'
),
[
'
-e
'
,
modulePath
].
concat
(
args
),
options
).
then
((
child
)
=>
{
readline
.
createInterface
({
input
:
child
.
stdout
}).
on
(
'
line
'
,
(
line
)
=>
{
child
.
emit
(
'
message
'
,
JSON
.
parse
(
line
));
});
child
.
send
=
(
message
,
sendHandle
,
options
,
callback
)
=>
{
child
.
stdin
.
write
(
JSON
.
stringify
(
message
)
+
os
.
EOL
);
if
(
callback
)
{
callback
()
}
};
return
child
})
};
@
Injectable
()
export
class
AppsService
{
constructor
(
private
http
:
Http
,
private
settingsService
:
SettingsService
,
private
ref
:
ApplicationRef
,
private
ngZong
:
NgZone
)
{
private
apps
:
Map
<
string
,
App
>
;
constructor
(
private
http
:
Http
,
private
settingsService
:
SettingsService
,
private
ref
:
ApplicationRef
,)
{
}
...
...
@@ -43,7 +46,8 @@ export class AppsService {
.
toPromise
()
.
then
((
response
)
=>
{
let
data
=
response
.
json
();
return
this
.
loadAppsList
(
data
);
this
.
apps
=
this
.
loadAppsList
(
data
);
return
this
.
apps
;
});
}
...
...
@@ -122,55 +126,52 @@ export class AppsService {
return
apps
;
};
deleteFile
(
path
:
string
):
Promise
<
string
>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
fs
.
lstat
(
path
,
(
err
,
stats
)
=>
{
if
(
err
)
return
resolve
(
path
);
if
(
stats
.
isDirectory
())
{
fs
.
rmdir
(
path
,
(
err
)
=>
{
resolve
(
path
);
});
}
else
{
fs
.
unlink
(
path
,
(
err
)
=>
{
resolve
(
path
);
});
}
});
})
findChildren
(
app
:
App
):
App
[]
{
let
children
=
[];
for
(
let
child
of
this
.
apps
.
values
())
{
if
(
child
.
parent
===
app
)
{
children
.
push
(
child
);
}
}
return
children
;
}
saveAppLocal
(
app
:
App
,
appLocal
:
AppLocal
)
{
localStorage
.
setItem
(
app
.
id
,
JSON
.
stringify
(
appLocal
));
}
runApp
(
app
:
App
)
{
let
children
=
this
.
findChildren
(
app
);
let
cwd
=
app
.
local
.
path
;
let
action
=
app
.
actions
.
get
(
'
main
'
);
let
args
=
[];
let
env
=
{};
for
(
let
child
of
children
)
{
action
=
child
.
actions
.
get
(
'
main
'
);
}
let
execute
=
path
.
join
(
cwd
,
action
.
execute
);
if
(
action
.
open
)
{
let
openAction
=
action
.
open
.
actions
.
get
(
'
main
'
);
args
=
args
.
concat
(
openAction
.
args
);
args
.
push
(
action
.
execute
);
execute
=
path
.
join
(
action
.
open
.
local
.
path
,
openAction
.
execute
);
env
=
Object
.
assign
(
env
,
openAction
.
env
);
}
args
=
args
.
concat
(
action
.
args
);
env
=
Object
.
assign
(
env
,
action
.
env
);
let
handle
=
child_process
.
spawn
(
execute
,
args
,
{
env
:
env
,
cwd
:
cwd
});
install
(
config
:
InstallConfig
)
{
let
app
=
config
.
app
;
}
handle
.
stdout
.
on
(
'
data
'
,
(
data
)
=>
{
console
.
log
(
`stdout:
${
data
}
`
)
;
});
uninstall
(
id
:
string
)
{
// //let current = this;
// if (this.checkInstall(id)) {
// let files: string[] = this.searchApp(id).local.files.sort().reverse();
// // 删除本目录
// files.push('.');
// let install_dir = this.searchApp(id).local.path;
// return files
// .map((file)=>
// ()=>path.join(install_dir, file)
// )
// .reduce((promise: Promise<string>, task)=>
// promise.then(task).then(this.deleteFile)
// , Promise.resolve(''))
// .then((value)=> {
// this.searchApp(id).local = null;
// localStorage.setItem("localAppData", JSON.stringify(this.data));
// return Promise.resolve()
// });
// }
handle
.
stderr
.
on
(
'
data
'
,
(
data
)
=>
{
console
.
log
(
`stderr:
${
data
}
`
);
});
}
handle
.
on
(
'
close
'
,
(
code
)
=>
{
console
.
log
(
`child process exited with code
${
code
}
`
);
remote
.
getCurrentWindow
().
restore
();
});
remote
.
getCurrentWindow
().
minimize
();
}
browse
(
app
:
App
)
{
remote
.
shell
.
showItemInFolder
(
app
.
local
.
path
);
...
...
@@ -179,60 +180,55 @@ export class AppsService {
connections
=
new
Map
<
App
,
{
connection
:
WebSocket
,
address
:
string
}
>
();
maotama
;
async
network
(
app
:
App
,
server
)
{
network
(
app
:
App
,
server
)
{
if
(
!
this
.
maotama
)
{
this
.
maotama
=
new
Sudo
({
name
:
'
MyCard
'
}).
fork
(
'
maotama
'
)
}
let
child
=
await
this
.
maotama
;
// child.on('message', console.log);
// child.on('exit', console.log);
// child.on('error', console.log);
let
connection
=
this
.
connections
.
get
(
app
);
if
(
connection
)
{
connection
.
connection
.
close
();
}
connection
=
{
connection
:
new
WebSocket
(
server
.
url
),
address
:
null
};
let
id
;
this
.
connections
.
set
(
app
,
connection
);
connection
.
connection
.
onmessage
=
(
event
)
=>
{
console
.
log
(
event
.
data
);
let
[
action
,
args
]
=
event
.
data
.
split
(
'
'
,
2
);
let
[
address
,
port
]
=
args
.
split
(
'
:
'
);
switch
(
action
)
{
case
'
LISTEN
'
:
connection
.
address
=
args
;
this
.
ref
.
tick
();
break
;
case
'
CONNECT
'
:
this
.
ngZong
.
runOutsideAngular
(()
=>
{
this
.
maotama
.
then
((
child
)
=>
{
let
connection
=
this
.
connections
.
get
(
app
);
if
(
connection
)
{
connection
.
connection
.
close
();
}
connection
=
{
connection
:
new
WebSocket
(
server
.
url
),
address
:
null
};
let
id
;
this
.
connections
.
set
(
app
,
connection
);
connection
.
connection
.
onmessage
=
(
event
)
=>
{
console
.
log
(
event
.
data
);
let
[
action
,
args
]
=
event
.
data
.
split
(
'
'
,
2
);
let
[
address
,
port
]
=
args
.
split
(
'
:
'
);
switch
(
action
)
{
case
'
LISTEN
'
:
connection
.
address
=
args
;
this
.
ref
.
tick
();
break
;
case
'
CONNECT
'
:
id
=
setInterval
(()
=>
{
child
.
send
({
action
:
'
connect
'
,
arguments
:
[
app
.
network
.
port
,
port
,
address
]
})
},
200
);
});
break
;
case
'
CONNECTED
'
:
break
;
case
'
CONNECTED
'
:
clearInterval
(
id
);
id
=
null
;
break
;
}
};
connection
.
connection
.
onclose
=
(
event
:
CloseEvent
)
=>
{
if
(
id
)
{
clearInterval
(
id
);
id
=
null
;
break
;
}
};
connection
.
connection
.
onclose
=
(
event
:
CloseEvent
)
=>
{
if
(
id
)
{
clearInterval
(
id
);
}
// 如果还是在界面上显示的那个连接
if
(
this
.
connections
.
get
(
app
)
==
connection
)
{
this
.
connections
.
delete
(
app
);
if
(
event
.
code
!=
1000
&&
!
connection
.
address
)
{
// 如果还没建立好就出错了,就弹窗提示这个错误
alert
(
`出错了
${
event
.
code
}
`
);
}
// 如果还是在界面上显示的那个连接
if
(
this
.
connections
.
get
(
app
)
==
connection
)
{
this
.
connections
.
delete
(
app
);
if
(
event
.
code
!=
1000
&&
!
connection
.
address
)
{
alert
(
`出错了
${
event
.
code
}
`
);
}
}
// 如果还没建立好就出错了,就弹窗提示这个错误
this
.
ref
.
tick
();
}
}
;
}
;
}
)
}
}
\ No newline at end of file
app/install.service.ts
View file @
d97349d0
...
...
@@ -14,6 +14,7 @@ import {EventEmitter} from "events";
import
{
AppLocal
}
from
"
./app-local
"
;
import
{
Http
}
from
"
@angular/http
"
;
import
ReadableStream
=
NodeJS
.
ReadableStream
;
import
{
AppsService
}
from
"
./apps.service
"
;
@
Injectable
()
export
class
InstallService
{
...
...
@@ -25,7 +26,7 @@ export class InstallService {
checksumUri
=
"
http://thief.mycard.moe/checksums/
"
;
constructor
(
private
http
:
Http
)
{
constructor
(
private
http
:
Http
,
private
appsService
:
AppsService
)
{
if
(
process
.
platform
===
"
win32
"
)
{
this
.
tarPath
=
path
.
join
(
process
.
resourcesPath
,
'
bin/tar.exe
'
);
}
else
{
...
...
@@ -43,7 +44,6 @@ export class InstallService {
getComplete
(
app
:
App
):
Promise
<
App
>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
eventEmitter
.
once
(
app
.
id
,
(
complete
)
=>
{
console
.
log
(
"
receive
"
,
app
.
id
);
resolve
();
});
});
...
...
@@ -103,9 +103,7 @@ export class InstallService {
saveAppLocal
(
app
:
App
)
{
if
(
app
.
local
)
{
let
a
=
JSON
.
stringify
(
app
.
local
)
console
.
log
(
a
);
localStorage
.
setItem
(
app
.
id
,
a
);
localStorage
.
setItem
(
app
.
id
,
JSON
.
stringify
(
app
.
local
));
}
}
...
...
@@ -164,7 +162,6 @@ export class InstallService {
local
.
version
=
app
.
version
;
app
.
local
=
local
;
this
.
saveAppLocal
(
app
);
console
.
log
(
"
send
"
,
app
.
id
);
this
.
eventEmitter
.
emit
(
app
.
id
,
'
install complete
'
);
this
.
installQueue
.
delete
(
app
);
this
.
installingQueue
.
delete
(
app
);
...
...
@@ -184,4 +181,55 @@ export class InstallService {
}
}
deleteFile
(
file
:
string
):
Promise
<
string
>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
fs
.
lstat
(
file
,
(
err
,
stats
)
=>
{
if
(
err
)
return
resolve
(
path
);
if
(
stats
.
isDirectory
())
{
fs
.
rmdir
(
file
,
(
err
)
=>
{
resolve
(
file
);
});
}
else
{
fs
.
unlink
(
file
,
(
err
)
=>
{
resolve
(
file
);
});
}
});
})
}
async
uninstall
(
app
:
App
)
{
if
(
!
app
.
parent
)
{
let
children
=
this
.
appsService
.
findChildren
(
app
);
for
(
let
child
of
children
)
{
if
(
child
.
isInstalled
())
{
await
this
.
uninstall
(
child
);
}
}
}
let
files
=
Array
.
from
(
app
.
local
.
files
.
keys
()).
sort
().
reverse
();
console
.
log
(
files
);
for
(
let
file
of
files
)
{
let
oldFile
=
file
;
if
(
!
path
.
isAbsolute
(
file
))
{
oldFile
=
path
.
join
(
app
.
local
.
path
,
file
);
}
await
this
.
deleteFile
(
oldFile
);
if
(
app
.
parent
)
{
let
backFile
=
path
.
join
(
app
.
local
.
path
,
"
backup
"
,
file
);
await
new
Promise
((
resolve
,
reject
)
=>
{
fs
.
rename
(
backFile
,
oldFile
,
resolve
);
});
}
}
if
(
app
.
parent
)
{
await
this
.
deleteFile
(
path
.
join
(
app
.
local
.
path
,
"
backup
"
));
}
else
{
await
this
.
deleteFile
(
app
.
local
.
path
);
}
app
.
local
=
null
;
localStorage
.
removeItem
(
app
.
id
);
}
}
\ No newline at end of file
app/mycard.component.html
View file @
d97349d0
<nav
class=
"navbar navbar-dark bg-inverse"
[class.darwin]=
"platform == 'darwin'"
>
<a
class=
"navbar-brand"
href=
"#"
>
MyCard
1
</a>
<a
class=
"navbar-brand"
href=
"#"
>
MyCard
</a>
<ul
class=
"nav navbar-nav"
>
<li
*ngIf=
"!loginService.user"
class=
"nav-item active"
>
<a
class=
"nav-link"
href=
"#"
>
登录
<span
class=
"sr-only"
>
(current)
</span></a>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment