Commit 56940564 authored by 神楽坂玲奈's avatar 神楽坂玲奈

改了好多东西?

parent ff09c0dd
......@@ -13,7 +13,6 @@ import { CubesService } from './cubes.service';
import { SettingsService } from './settings.sevices';
import { LoginService } from './login.service';
import { DownloadService } from './download.service';
import { AppRoutingModule } from './app-routing.module';
import { AuthGuard } from './auth.guard';
import { ProgressSpinnerComponent } from './progress-spinner/progress-spinner.component';
import { CommunityComponent } from './community/community.component';
......@@ -26,13 +25,13 @@ import { CubeDescriptionComponent } from './cube-description/cube-description.co
import { CubeNewsComponent } from './cube-news/cube-news.component';
import { CubeExpansionsComponent } from './cube-expansions/cube-expansions.component';
import { ProgressBarComponent } from './progress-bar/progress-bar.component';
import { ELECTRON_SCHEMA } from './electron-schema';
import { ELECTRON_SCHEMA } from 'electron-schema';
import { MaotamaComponent } from './maotama/maotama.component';
import { ProfileComponent } from './profile/profile.component';
import { RoutingService } from './routing.sevices';
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule, AppRoutingModule],
imports: [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule],
declarations: [
MoeCubeComponent, LoginComponent, LobbyComponent,
CubeDetailComponent, RosterComponent, YGOProComponent, CandyComponent,
......@@ -42,7 +41,8 @@ import { ProfileComponent } from './profile/profile.component';
],
bootstrap: [MoeCubeComponent],
providers: [
CubesService, SettingsService, LoginService, DownloadService, AuthGuard, LoadingGuard
CubesService, SettingsService, LoginService, DownloadService, RoutingService
// , AuthGuard, LoadingGuard,
// 执行 xi18n 的时候注释掉这几行
// , {
// provide: LOCALE_ID,
......
......@@ -10,6 +10,9 @@ import 'node_modules/candy-shop/notifications/candy.js';
import 'node_modules/candy-shop/refocus/candy.js';
import { LoginService } from '../login.service';
import { SettingsService } from '../settings.sevices';
import * as uuid from 'uuid';
// import * as jqueryShadow from '../../jquery-shadow.js';
// import 'electron-cookies';
/**
* Created by zh99998 on 16/9/2.
*/
......@@ -213,7 +216,7 @@ declare const $iq: any;
})
export class CandyComponent implements OnInit, OnChanges {
@Input()
currentApp: Cube;
currentCube: Cube;
jid: string;
password: string;
nickname: string;
......@@ -226,7 +229,7 @@ export class CandyComponent implements OnInit, OnChanges {
ngOnInit() {
this.jid = this.loginService.user.username + '@moecube.com';
this.jid = this.loginService.user.username + '@mycard.moe';
this.password = this.loginService.user.external_id.toString();
this.nickname = this.loginService.user.username;
......@@ -260,11 +263,13 @@ export class CandyComponent implements OnInit, OnChanges {
</form>
`;
Candy.Util.setCookie('candy-nostatusmessages', '1', 365);
Candy.init('wss://chat.moecube.com:5280/websocket', {
core: {
debug: false,
autojoin: this.currentApp.conference && [this.currentApp.conference + '@conference.moecube.com'],
resource: 'moecube-' + Math.random().toString().split('.')[1]
autojoin: this.currentCube.conference && [this.currentCube.conference + '@conference.mycard.moe'],
resource: uuid.v1()
},
view: {
assets: 'node_modules/candy/res/',
......@@ -303,7 +308,7 @@ export class CandyComponent implements OnInit, OnChanges {
if (!Candy.Core.getConnection()) {
return;
}
let conference = changes['currentApp'].currentValue.conference;
let conference = changes['currentCube'].currentValue.conference;
if (!conference) {
return;
}
......
:host {
display: flex;
flex: 1;
}
:host, webview {
flex: 1;
:host[hidden] {
display: flex !important;
width: 0;
height: 0;
flex: 0 1;
}
<webview src="https://ygobbs.com" (new-window)="openExternal($event.url)"></webview>
......@@ -3,14 +3,18 @@
*/
import { Component } from '@angular/core';
import { shell } from 'electron';
import { RoutingService } from '../routing.sevices';
@Component({
selector: 'community',
templateUrl: './community.component.html',
selector: 'webview[community]',
template: '',
styleUrls: ['./community.component.css'],
host: { '[src]': 'routingService.currentCommunityURL', '(new-window)': 'shell.openExternal($event.url)' }
})
export class CommunityComponent {
openExternal(url: string) {
shell.openExternal(url);
public shell = shell;
constructor(public routingService: RoutingService) {
}
}
......@@ -5,7 +5,6 @@ import { ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnInit, Sim
import { Cube, InstallOption } from '../cube';
import { CubesService } from '../cubes.service';
import { SettingsService } from '../settings.sevices';
import { ActivatedRoute } from '@angular/router';
import { LoginService } from '../login.service';
import { DownloadService } from '../download.service';
import { Http } from '@angular/http';
......@@ -40,7 +39,7 @@ export class CubeActionsComponent implements OnInit, OnChanges {
constructor(private cubesService: CubesService, private settingsService: SettingsService,
private downloadService: DownloadService, private ref: ChangeDetectorRef, private el: ElementRef,
private http: Http, private loginService: LoginService, private route: ActivatedRoute) {
private http: Http, private loginService: LoginService) {
}
async ngOnInit(): Promise<void> {
......
import { ChangeDetectorRef, Component, ElementRef, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { clipboard, remote } from 'electron';
import * as path from 'path';
import * as fs from 'fs';
......@@ -9,7 +9,6 @@ import { CubesService } from '../cubes.service';
import { SettingsService } from '../settings.sevices';
import { DownloadService } from '../download.service';
import { LoginService } from '../login.service';
import { ActivatedRoute, Params } from '@angular/router';
declare const Notification: any;
......@@ -26,6 +25,7 @@ declare const Notification: any;
styleUrls: ['./cube-detail.component.css'],
})
export class CubeDetailComponent implements OnInit, OnChanges {
@Input()
currentCube: Cube;
platform = process.platform;
......@@ -46,7 +46,7 @@ export class CubeDetailComponent implements OnInit, OnChanges {
constructor(private cubesService: CubesService, private settingsService: SettingsService,
private downloadService: DownloadService, private ref: ChangeDetectorRef, private el: ElementRef,
private http: Http, private loginService: LoginService, private route: ActivatedRoute) {
private http: Http, private loginService: LoginService) {
this.tags = this.settingsService.getLocale().startsWith('zh') ? {
'recommend': '推荐',
......@@ -64,20 +64,20 @@ export class CubeDetailComponent implements OnInit, OnChanges {
}
async ngOnInit(): Promise<void> {
this.route.params
.switchMap((params: Params) => this.cubesService.getCube(params['id']))
.subscribe(async (cube: Cube) => {
this.currentCube = cube;
this.cubesService.lastVisited = cube;
if (this.currentCube.background) {
this.el.nativeElement.style.background = `url("${this.currentCube.background}") rgba(255,255,255,.8)`;
} else {
this.el.nativeElement.style.background = 'white';
}
// let top = await this.http.get('https://ygobbs.com/top.json').map(response => response.json()).toPromise();
// console.log(top.topic_list.topics);
});
// this.route.params
// .switchMap((params: Params) => this.cubesService.getCube(params['id']))
// .subscribe(async (cube: Cube) => {
// this.currentCube = cube;
// this.cubesService.lastVisited = cube;
// if (this.currentCube.background) {
// this.el.nativeElement.style.background = `url("${this.currentCube.background}") rgba(255,255,255,.8)`;
// } else {
// this.el.nativeElement.style.background = 'white';
// }
//
// // let top = await this.http.get('https://ygobbs.com/top.json').map(response => response.json()).toPromise();
// // console.log(top.topic_list.topics);
// });
let volume = 'A';
for (let i = 0; i < 26; i++) {
......@@ -97,6 +97,14 @@ export class CubeDetailComponent implements OnInit, OnChanges {
}
async ngOnChanges(changes: SimpleChanges) {
if (changes.currentCube) {
if (this.currentCube.background) {
this.el.nativeElement.style.background = `url("${this.currentCube.background}") rgba(255,255,255,.8)`;
} else {
this.el.nativeElement.style.background = 'white';
}
}
if (this.currentCube.isBought()) {
$('#purchase-modal-alipay').modal('hide');
}
......
......@@ -106,11 +106,7 @@ export class CubesService {
// 这里必须返回个 Promise,于是不能去掉 async
async getCube(id: string) {
let result = this.apps.get(id);
if (!result) {
throw 'not found';
}
return result;
return this.apps.get(id);
}
async migrate() {
......
import { DomElementSchemaRegistry } from '@angular/compiler';
import { SchemaMetadata } from '@angular/core';
const tags: Object = {
webview: {
src: true,
autosize: true,
nodeintegration: true,
plugins: true,
preload: true,
httpreferrer: true,
useragent: true,
disablewebsecurity: true,
partition: true,
allowpopups: true,
webpreferences: true,
blinkfeatures: true,
disableblinkfeatures: true,
guestinstance: true,
disableguestresize: true
}
};
export const ELECTRON_SCHEMA: SchemaMetadata = {
name: 'electron-schema'
};
DomElementSchemaRegistry.prototype.hasElement = new Proxy(DomElementSchemaRegistry.prototype.hasElement, {
apply(target, thisArgument, argumentsList) {
const [tagName, schemaMetas] = argumentsList;
if (schemaMetas.some((schema: SchemaMetadata) => schema.name === ELECTRON_SCHEMA.name) && tags[tagName]) {
return true;
}
return Reflect.apply(target, thisArgument, argumentsList);
}
});
DomElementSchemaRegistry.prototype.hasProperty = new Proxy(DomElementSchemaRegistry.prototype.hasProperty, {
apply(target, thisArgument, argumentsList) {
const [tagName, propName, schemaMetas] = argumentsList;
if (schemaMetas.some((schema: SchemaMetadata) => schema.name === ELECTRON_SCHEMA.name) && tags[tagName] && tags[tagName][propName]) {
return true;
}
return Reflect.apply(target, thisArgument, argumentsList);
}
});
......@@ -3,19 +3,18 @@
<nav id="apps" *ngIf="apps" class="bg-faded sidebar scroll">
<div id="search" class="input-group">
<i class="fa fa-search input-group-addon search" id="basic-addon1"></i>
<input #search id="search-input" type="text" class="form-control search" placeholder="搜索游戏"
aria-describedby="basic-addon1">
<input #search id="search-input" type="text" class="form-control search" placeholder="搜索游戏" aria-describedby="basic-addon1">
</div>
<ng-container *ngFor="let tag of tags">
<ng-container *ngIf="grouped_apps[tag]">
<span i18n>{tag, select, installed {已安装} test {测试} recommend {推荐} mysterious {迷之物体} touhou {东方 Project} touhou_pc98 {东方旧作} runtime_installed {已安装的运行库} }</span>
<ul class="nav nav-pills flex-column">
<li *ngFor="let app of grouped_apps[tag]" class="nav-item">
<a [routerLink]="app.id" routerLinkActive="active" class="nav-link">
<img *ngIf="app.icon" class="icon" [src]="app.icon">
{{app.name}}
<progress-spinner *ngIf="app.isWorking()" [value]="app.status.progress / app.status.total"></progress-spinner>
<li *ngFor="let cube of grouped_apps[tag]" class="nav-item">
<a (click)="currentCube = cube" [class.active]="currentCube === cube" class="nav-link">
<img *ngIf="cube.icon" class="icon" [src]="cube.icon">
{{cube.name}}
<progress-spinner *ngIf="cube.isWorking()" [value]="cube.status.progress / cube.status.total"></progress-spinner>
</a>
</li>
</ul>
......@@ -28,13 +27,14 @@
<div id="right">
<div id="main">
<router-outlet></router-outlet>
<cube-detail *ngIf="currentCube" [currentCube]="currentCube"></cube-detail>
<!--<router-outlet></router-outlet>-->
<roster class="scroll"></roster>
</div>
<div id="candy-wrapper" class="resize-wrapper resize-top" style="max-height: calc( 100% - 180px )">
<div class="resize" (mousedown)="mousedown($event)"></div>
<candy *ngIf="currentApp" [currentApp]="currentApp"></candy>
<candy *ngIf="currentCube" [currentCube]="currentCube"></candy>
</div>
</div>
......
......@@ -2,13 +2,11 @@
* Created by zh99998 on 16/9/2.
*/
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { shell } from 'electron';
import { URLSearchParams } from '@angular/http';
import { Category, Cube } from '../cube';
import { CubesService } from '../cubes.service';
import { LoginService } from '../login.service';
import { SettingsService } from '../settings.sevices';
import { ActivatedRoute, Router } from '@angular/router';
import * as ReconnectingWebSocket from 'reconnecting-websocket';
// import 'typeahead.js';
......@@ -25,7 +23,7 @@ export class LobbyComponent implements OnInit {
readonly tags = ['installed', 'recommend', 'test', 'mysterious', 'touhou', 'touhou_pc98', 'runtime_installed'];
currentApp: Cube;
currentCube: Cube;
private apps: Map<string, Cube>;
resizing: HTMLElement | undefined;
......@@ -36,29 +34,42 @@ export class LobbyComponent implements OnInit {
private messages: WebSocket;
constructor(private appsService: CubesService, private loginService: LoginService,
private settingsService: SettingsService, private ref: ChangeDetectorRef,
private route: ActivatedRoute, private router: Router) {
constructor(private cubesService: CubesService, private loginService: LoginService,
private settingsService: SettingsService, private ref: ChangeDetectorRef) {
}
async ngOnInit() {
try {
this.apps = await this.appsService.loadCubes();
this.apps = await this.cubesService.loadCubes();
} catch (error) {
console.error(error);
// if (confirm('获取程序列表失败,是否重试?')) {
// location.reload();
// } else {
// window.close();
// }
if (confirm('获取程序列表失败,是否重试?')) {
location.reload();
} else {
window.close();
}
return;
}
await this.router.navigate(['lobby', this.appsService.lastVisited ? this.appsService.lastVisited.id : 'ygopro']);
this.currentCube = this.cubesService.lastVisited || this.apps.get('ygopro')!;
// this.route.params
// .switchMap((params: Params) => this.cubesService.getCube(params['id']))
// .subscribe((cube: Cube) => {
// if (cube) {
// this.currentCube = cube;
// this.cubesService.lastVisited = cube;
// } else {
// this.router.navigate(['lobby', this.cubesService.lastVisited ? this.cubesService.lastVisited.id : 'ygopro']);
// }
//
// // let top = await this.http.get('https://ygobbs.com/top.json').map(response => response.json()).toPromise();
// // console.log(top.topic_list.topics);
// });
await this.appsService.migrate();
await this.cubesService.migrate();
for (let app of this.apps.values()) {
await this.appsService.update(app);
await this.cubesService.update(app);
}
// 特化个 YGOPRO 国际服聊天室。其他的暂时没需求。
......@@ -75,8 +86,8 @@ export class LobbyComponent implements OnInit {
this.messages.onmessage = async (event) => {
let data = JSON.parse(event.data);
console.log(data);
this.apps = await this.appsService.loadCubes();
this.currentApp = this.apps.get(this.currentApp.id)!;
this.apps = await this.cubesService.loadCubes();
this.currentCube = this.apps.get(this.currentCube.id)!;
};
......@@ -170,8 +181,7 @@ export class LobbyComponent implements OnInit {
}
select(app: Cube) {
this.appsService.lastVisited = app;
this.cubesService.lastVisited = app;
}
......@@ -201,8 +211,4 @@ export class LobbyComponent implements OnInit {
}
return result;
}
openExternal(url: string) {
shell.openExternal(url);
}
}
:host {
flex: 1;
display: flex;
}
webview {
flex-grow: 1;
}
<webview [src]="url" (will-navigate)="return_sso($event.url)" (did-get-redirect-request)="return_sso($event.newURL)"
(new-window)="openExternal($event.url)"></webview>
......@@ -8,15 +8,22 @@ import { LoginService } from '../login.service';
import { Router } from '@angular/router';
@Component({
selector: 'login',
templateUrl: './login.component.html',
selector: 'webview[login]',
template: '',
styleUrls: ['./login.component.css'],
host: {
'[src]': 'url',
'(will-navigate)': 'return_sso($event.url)',
'(did-get-redirect-request)': 'return_sso($event.newURL)',
'(new-window)': 'openExternal($event.url)'
}
})
export class LoginComponent implements OnInit {
shell = shell;
url: string;
readonly return_sso_url = 'https://moecube.com/login_callback'; // 这个url不会真的被使用,可以填写不存在的
constructor(private router: Router, private loginService: LoginService) {
constructor(private loginService: LoginService) {
}
ngOnInit() {
......@@ -55,7 +62,7 @@ export class LoginComponent implements OnInit {
// 这里是 TypeScript 的一个bug,https://github.com/Microsoft/TypeScript/issues/15243
let user = this.toObject(<any>new URLSearchParams(Buffer.from(token, 'base64').toString()));
this.loginService.login(user);
this.router.navigate(['/']);
// this.router.navigate(['/']);
}
toObject(entries: Iterable<[string, any]>): any {
......@@ -65,8 +72,4 @@ export class LoginComponent implements OnInit {
}
return result;
}
openExternal(url: string) {
shell.openExternal(url);
}
}
<nav id="navbar" class="navbar navbar-toggleable-md navbar-light">
<a id="navbar-brand" class="navbar-brand" href="#">MoeCube</a>
<ul class="navbar-nav mr-auto">
<ng-template #login>
<ng-template #loginNav>
<li class="nav-item active"><a i18n class="nav-link" href="#">登录</a></li>
</ng-template>
<ng-container *ngIf="loginService.logged_in; else login">
<li routerLinkActive="active" class="nav-item"><a i18n routerLink="lobby" class="nav-link" href="#">游戏</a></li>
<li routerLinkActive="active" class="nav-item"><a i18n routerLink="community" class="nav-link" href="#">社区</a>
<ng-container *ngIf="loginService.logged_in; else loginNav">
<li [class.active]="currentPage === 'lobby'" class="nav-item">
<a i18n (click)="currentPage = 'lobby'" class="nav-link" href="#">游戏</a>
</li>
<li [class.active]="currentPage === 'community'" class="nav-item">
<a i18n (click)="currentPage = 'community'" class="nav-link" href="#">社区</a>
</li>
</ng-container>
......@@ -16,14 +19,14 @@
<update></update>
<ul class="navbar-nav mr-auto" *ngIf="loginService.logged_in">
<li routerLinkActive="active" class="nav-item dropdown">
<li [class.active]="currentPage === 'profile'" class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button">
<img id="avatar" [src]="loginService.user.avatar_url" alt="avatar">
{{loginService.user.username}}
</a>
<div class="dropdown-menu">
<a i18n class="dropdown-item" routerLink="profile">个人资料</a>
<a i18n (click)="loginService.logout()" routerLink="login" class="dropdown-item">切换用户</a>
<a i18n class="dropdown-item" (click)="currentPage = 'profile'">个人资料</a>
<a i18n (click)="loginService.logout()" class="dropdown-item">切换用户</a>
<a i18n data-toggle="modal" data-target="#settings-modal" class="dropdown-item" href="#">设置</a>
</div>
</li>
......@@ -33,7 +36,14 @@
</div>
</nav>
<router-outlet></router-outlet>
<ng-template #login>
<webview login></webview>
</ng-template>
<ng-container *ngIf="loginService.logged_in; else login">
<lobby [hidden]="currentPage !== 'lobby'"></lobby>
<webview community [hidden]="currentPage !== 'community'"></webview>
<webview profile *ngIf="currentPage === 'profile'"></webview>
</ng-container>
<!-- Modal -->
<div class="modal fade" id="settings-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
......
......@@ -13,6 +13,7 @@ import { SettingsService } from '../settings.sevices';
export class MoeCubeComponent implements OnInit {
locale: string;
currentPage = 'lobby';
constructor(public loginService: LoginService, private settingsService: SettingsService) {
}
......
:host {
flex: 1;
display: flex;
}
webview {
flex-grow: 1;
}
<webview src="https://accounts.moecube.com/profiles" (new-window)="openExternal($event.url)"></webview>
......@@ -7,9 +7,11 @@ declare const URLSearchParams: any;
@Component({
selector: 'profile',
templateUrl: './profile.component.html',
selector: 'webview[profile]',
template: '',
styleUrls: ['./profile.component.css'],
host: { 'src': 'https://accounts.moecube.com/profiles', '(new-window)': 'openExternal($event.url)' }
})
export class ProfileComponent {
}
/**
* Created by weijian on 2016/10/24.
*/
import { Injectable } from '@angular/core';
import { Cube } from './cube';
interface Community {
id: string,
url: string
}
@Injectable()
export class RoutingService {
currentPage = 'lobby';
currentCube: Cube;
communities = [
{ id: 'ygopro', url: 'http://ygobbs.com' },
{ id: 'oz', url: 'http://fuckoz.com' }
];
currentCommunity = this.communities[0];
currentCommunityURL = this.currentCommunity.url;
navigate(page, item?: Cube | Community, url?) {
this.currentPage = page;
switch (page) {
case 'community':
if (item) {
this.currentCommunity = <Community>item;
}
if (url) {
this.currentCommunityURL = url;
}
break;
case 'lobby':
if (item) {
this.currentCube = <Cube>item;
}
break;
}
}
getCommunity(id) {
return this.communities.find((item) => item.id === id);
}
}
......@@ -76,7 +76,13 @@
'tether': 'npm:tether/dist/js/tether.min.js',
'bootstrap': 'npm:bootstrap/dist/js/bootstrap.min.js',
'reconnecting-websocket': 'npm:reconnecting-websocket/dist/index.js',
'reflect-metadata': 'npm:reflect-metadata/Reflect.js'
'reflect-metadata': 'npm:reflect-metadata/Reflect.js',
'electron-schema': 'npm:electron-schema/index.js',
'electron-cookies': 'npm:electron-cookies/src/index.js',
'uuid': '@node/uuid',
'candy': 'npm:candy/candy.min.js',
'candy-libs': 'npm:candy/libs.min.js',
'candy-shop': 'npm:candy-shop/index.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
......
......@@ -10,9 +10,10 @@
"es2017",
"dom"
],
"noImplicitAny": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true,
"strictNullChecks": true,
"skipLibCheck": true
"skipLibCheck": true,
"allowJs": true
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment