-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection manager replacement #573
Merged
manuelwedler
merged 17 commits into
raiden-network:master
from
manuelwedler:connection-manager-replacement
Dec 2, 2020
Merged
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
cfeb952
Make 360px the default dialog width to remove config duplication
manuelwedler 8777585
Query settings endpoint from API
manuelwedler 10c741c
Query token network address from API
manuelwedler 08920ca
Make TokenInputComponent more flexible and adjust layout
manuelwedler e5d66f8
Set a BigNumber value programmatically on TokenInputComponent
manuelwedler 13c24ea
Use UserToken objects as form control value of TokenNetworkSelectorCo…
manuelwedler 2aca12c
Add structure of new QuickConnectDialogComponent and fetch pfs sugges…
manuelwedler 9025024
Introduce constant explorerUrl on Network object
manuelwedler f38c49f
Add ConnectionSelectorComponent to complete QuickConnectDialog
manuelwedler ca0e91e
Add tests for ConnectionSelectorComponent
manuelwedler 2bcd89d
Add tests for QuickConnectDialogComponent
manuelwedler 7879794
Add method for opening a batch of channels to RaidenService
manuelwedler 2dcb273
Open QuickConnectDialog from TokenComponent
manuelwedler 40c4db9
Remove functionality related to the connection manager
manuelwedler 9fad78e
Add button for accessing Quick Connect directly from tokens view
manuelwedler 9589332
Updates CHANGELOG
manuelwedler f2ff5f9
Use defer() instead of of(null) for side effects on subscribe
manuelwedler File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
src/app/components/quick-connect-dialog/quick-connect-dialog.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<app-raiden-dialog | ||
titleText="Quick Connect" | ||
acceptText="Connect" | ||
[acceptDisabled]="form.invalid" | ||
[formGroup]="form" | ||
(accept)="accept()" | ||
(cancel)="cancel()" | ||
> | ||
<app-token-network-selector | ||
*ngIf="initiatedWithoutToken" | ||
formControlName="token" | ||
[showOnChainBalance]="true" | ||
> | ||
</app-token-network-selector> | ||
<app-token-input | ||
placeholder="Total Deposit" | ||
infoText="You will get suggested partners to connect to. Quick Connect will open channels with these suggestions. The total deposit is split among the channels. You can modify the deposit for each partner. By setting a deposit to 0 no channel will be created." | ||
formControlName="totalAmount" | ||
[onChainInput]="true" | ||
> | ||
</app-token-input> | ||
<div | ||
*ngIf="loading || pfsError || suggestions.length > 0" | ||
class="content" | ||
[@stretchVertically]="'in'" | ||
> | ||
<div *ngIf="!loading && !pfsError; else spinner"> | ||
Top suggestions: {{ suggestions }} | ||
</div> | ||
<ng-template #spinner> | ||
<div class="content__full" fxLayoutAlign="center center"> | ||
<mat-progress-spinner | ||
*ngIf="loading; else error" | ||
diameter="60" | ||
mode="indeterminate" | ||
color="primary" | ||
></mat-progress-spinner> | ||
</div> | ||
</ng-template> | ||
<ng-template #error> | ||
<div class="content__full error" fxLayoutAlign="center center"> | ||
Could not fetch any suggestions | ||
</div> | ||
</ng-template> | ||
</div> | ||
</app-raiden-dialog> |
17 changes: 17 additions & 0 deletions
17
src/app/components/quick-connect-dialog/quick-connect-dialog.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
@import '../../../sass/colors'; | ||
|
||
.content { | ||
height: 182px; | ||
|
||
&__full { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
} | ||
|
||
.error { | ||
font-size: 13px; | ||
line-height: 15px; | ||
letter-spacing: 0.35px; | ||
color: $red; | ||
} |
24 changes: 24 additions & 0 deletions
24
src/app/components/quick-connect-dialog/quick-connect-dialog.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { QuickConnectDialogComponent } from './quick-connect-dialog.component'; | ||
|
||
describe('QuickConnectDialogComponent', () => { | ||
let component: QuickConnectDialogComponent; | ||
let fixture: ComponentFixture<QuickConnectDialogComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
declarations: [QuickConnectDialogComponent], | ||
}).compileComponents(); | ||
}); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(QuickConnectDialogComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
183 changes: 183 additions & 0 deletions
183
src/app/components/quick-connect-dialog/quick-connect-dialog.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
import { HttpClient } from '@angular/common/http'; | ||
import { Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; | ||
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; | ||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; | ||
import { Animations } from 'app/animations/animations'; | ||
import { ConnectionChoice, SuggestedConnection } from 'app/models/connection'; | ||
import { UserToken } from 'app/models/usertoken'; | ||
import { ChannelPollingService } from 'app/services/channel-polling.service'; | ||
import { RaidenService } from 'app/services/raiden.service'; | ||
import { TokenPollingService } from 'app/services/token-polling.service'; | ||
import { combineLatest, Observable, Subject, zip } from 'rxjs'; | ||
import { | ||
catchError, | ||
filter, | ||
finalize, | ||
first, | ||
map, | ||
switchMap, | ||
takeUntil, | ||
tap, | ||
} from 'rxjs/operators'; | ||
import { TokenInputComponent } from '../token-input/token-input.component'; | ||
|
||
export interface QuickConnectDialogPayload { | ||
readonly token: UserToken; | ||
} | ||
|
||
export interface QuickConnectDialogResult { | ||
readonly token: UserToken; | ||
readonly connectionChoices: ConnectionChoice[]; | ||
} | ||
|
||
@Component({ | ||
selector: 'app-quick-connect-dialog', | ||
templateUrl: './quick-connect-dialog.component.html', | ||
styleUrls: ['./quick-connect-dialog.component.scss'], | ||
animations: Animations.stretchInOut, | ||
}) | ||
export class QuickConnectDialogComponent implements OnInit, OnDestroy { | ||
@ViewChild(TokenInputComponent, { static: true }) | ||
private tokenInput: TokenInputComponent; | ||
|
||
form: FormGroup; | ||
initiatedWithoutToken = false; | ||
suggestions: SuggestedConnection[] = []; | ||
loading = false; | ||
pfsError = false; | ||
|
||
private ngUnsubscribe = new Subject(); | ||
|
||
constructor( | ||
@Inject(MAT_DIALOG_DATA) data: QuickConnectDialogPayload, | ||
private dialogRef: MatDialogRef<QuickConnectDialogComponent>, | ||
private fb: FormBuilder, | ||
private tokenPollingService: TokenPollingService, | ||
private raidenService: RaidenService, | ||
private http: HttpClient, | ||
private channelPollingService: ChannelPollingService | ||
) { | ||
this.initiatedWithoutToken = !data.token; | ||
this.form = this.fb.group({ | ||
token: [data.token, Validators.required], | ||
totalAmount: ['', Validators.required], | ||
}); | ||
} | ||
|
||
ngOnInit(): void { | ||
this.subscribeToSuggestions(); | ||
this.subscribeToTokenUpdates(); | ||
this.form.controls.token.updateValueAndValidity(); | ||
} | ||
|
||
ngOnDestroy() { | ||
this.ngUnsubscribe.next(); | ||
this.ngUnsubscribe.complete(); | ||
} | ||
|
||
accept() { | ||
const payload: QuickConnectDialogResult = { | ||
token: this.form.value.token, | ||
connectionChoices: undefined, // TODO | ||
}; | ||
this.dialogRef.close(payload); | ||
} | ||
|
||
cancel() { | ||
this.dialogRef.close(); | ||
} | ||
|
||
private subscribeToSuggestions() { | ||
const pathfindingServiceUrl$ = this.raidenService | ||
.getSettings() | ||
.pipe(map((settings) => settings.pathfinding_service_address)); | ||
const tokenValueChange$: Observable<UserToken> = this.form.controls | ||
.token.valueChanges; | ||
const tokenNetworkAddress$ = tokenValueChange$.pipe( | ||
filter((token) => !!token), | ||
tap(() => { | ||
this.loading = true; | ||
this.resetError(); | ||
}), | ||
switchMap((token) => | ||
this.raidenService.getTokenNetworkAddress(token.address) | ||
) | ||
); | ||
|
||
const suggestions$ = combineLatest([ | ||
pathfindingServiceUrl$, | ||
tokenNetworkAddress$, | ||
]).pipe( | ||
switchMap(([pathfindingServiceUrl, tokenNetworkAddress]) => | ||
this.http.get<SuggestedConnection[]>( | ||
`${pathfindingServiceUrl}/api/v1/${tokenNetworkAddress}/suggest_partner` | ||
) | ||
) | ||
); | ||
const allChannels$ = this.channelPollingService.channels$.pipe(first()); | ||
const existingChannels$ = combineLatest([ | ||
tokenValueChange$, | ||
allChannels$, | ||
]).pipe( | ||
map(([token, channels]) => | ||
channels.filter( | ||
(channel) => | ||
channel.state !== 'settled' && | ||
channel.token_address === token.address | ||
) | ||
) | ||
); | ||
|
||
zip(suggestions$, existingChannels$) | ||
.pipe( | ||
map(([suggestions, channels]) => | ||
suggestions.filter( | ||
(suggestion) => | ||
!channels.find( | ||
(channel) => | ||
channel.partner_address === | ||
suggestion.address | ||
) | ||
) | ||
), | ||
catchError((error, caught) => { | ||
this.showError(); | ||
return caught; | ||
}), | ||
tap(() => (this.loading = false)), | ||
takeUntil(this.ngUnsubscribe) | ||
) | ||
.subscribe((suggestions) => { | ||
if (suggestions.length === 0) { | ||
this.showError(); | ||
} | ||
this.suggestions = suggestions; | ||
}); | ||
} | ||
|
||
private subscribeToTokenUpdates() { | ||
this.form.controls.token.valueChanges | ||
.pipe( | ||
tap((token) => (this.tokenInput.selectedToken = token)), | ||
switchMap((token) => | ||
this.tokenPollingService.getTokenUpdates( | ||
token?.address ?? '' | ||
) | ||
), | ||
takeUntil(this.ngUnsubscribe) | ||
) | ||
.subscribe((updatedToken) => { | ||
this.tokenInput.maxAmount = updatedToken?.balance; | ||
}); | ||
} | ||
|
||
private showError() { | ||
this.pfsError = true; | ||
this.form.controls.totalAmount.disable(); | ||
} | ||
|
||
private resetError() { | ||
this.pfsError = false; | ||
this.form.controls.totalAmount.enable(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,10 +22,6 @@ | |
|
||
&--black { | ||
color: $white; | ||
|
||
&:disabled { | ||
color: $dark-grey; | ||
} | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: private methods with internal, explicit subscriptions aren't usually the recommended way to do that in Angular. Maybe you could just initialize private cold observables, possibly
share
d, and then use| async
on template, which does handle subscriptions automatically. Declarative is usually better than imperative.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes totally sense! I like it your way better. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't make it because there were too many changes needed in the tests. Not worth the effort.