mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-25 06:05:52 +02:00
Archive commit
This commit is contained in:
@@ -0,0 +1,447 @@
|
||||
div(*ngIf="account")
|
||||
.row
|
||||
.col-md-12
|
||||
h2
|
||||
| {{account.name}}
|
||||
small.text-muted.ml-1
|
||||
em {{account.name | translit}}
|
||||
|
||||
.row
|
||||
.col-md-4
|
||||
.mb-2
|
||||
account-info([account]="account" popoverPlacement="right")
|
||||
.mb-2
|
||||
code.text-muted {{account._id}}
|
||||
.mb-2
|
||||
div
|
||||
span.text-muted created:
|
||||
from-now.ml-1([time]="account.createdAt")
|
||||
span.text-muted.ml-1 ({{account.createdAt | date}})
|
||||
div
|
||||
span.text-muted last visit:
|
||||
from-now.ml-1([time]="account.lastVisit")
|
||||
span.text-muted.ml-1 ({{account.lastVisit | date}})
|
||||
div
|
||||
span.text-muted last browser:
|
||||
ua-info.ml-1([userAgent]="accountObject?.lastUserAgent")
|
||||
div
|
||||
span.text-muted age:
|
||||
span([class.text-strike]="account.birthyear")
|
||||
span.ml-1 {{age}}
|
||||
span.text-muted.ml-1 ({{account.birthdate | date:'yyyy-MM-dd'}})
|
||||
span(*ngIf="account.birthyear")
|
||||
span.ml-1 {{forceAge}}
|
||||
span.text-muted.ml-1 ({{account.birthyear}})
|
||||
.d-inline-block.dropdown(dropdown)
|
||||
a.icon-button.ml-1(dropdownToggle)
|
||||
fa-icon([icon]="cogIcon")
|
||||
.dropdown-menu(*dropdownMenu)
|
||||
button.dropdown-item((click)="setAge(-1)")
|
||||
| unset
|
||||
button.dropdown-item(*ngFor="let age of ages" (click)="setAge(age)")
|
||||
| set to #[b {{age}}]yo
|
||||
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Counters
|
||||
div
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="refreshDetails()" title="Refresh account details")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
.mb-2
|
||||
div(*ngFor="let counter of counters")
|
||||
span.text-muted {{counter.key}}:
|
||||
span.ml-1 {{counter.value}}
|
||||
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Status
|
||||
div
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="clearSessions()" title="Sign out user" [disabled]="clearingSessions")
|
||||
fa-icon([icon]="clearingSessions ? spinnerIcon : signOutIcon" [fixedWidth]="true" [spin]="clearingSessions")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="showAccountData()" title="Fetch account data (in console)")
|
||||
fa-icon([icon]="consoleIcon" [fixedWidth]="true")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="accountStatus.refresh()" title="Refresh status")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
.mb-2
|
||||
account-status(#accountStatus [account]="account" [verbose]="true")
|
||||
|
||||
h5 Roles
|
||||
.mb-2
|
||||
.btn-group.btn-group-sm
|
||||
button.btn(*ngFor="let r of roles" [btnHighlight]="hasRole(r)" (click)="toggleRole(r)" [disabled]="!canToggleRole(r)")
|
||||
| {{r}}
|
||||
button.btn.btn-sm.btn-danger.ml-1((click)="remove()" [disabled]="!canRemove" title="Delete account")
|
||||
fa-icon([icon]="trashIcon" [fixedWidth]="true")
|
||||
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5
|
||||
| Notes
|
||||
a.text-muted.ml-1([href]="translateUrl(account.note)" target="_blank" title="Translate note")
|
||||
fa-icon([icon]="langIcon")
|
||||
.text-muted
|
||||
from-now([time]="account.noteUpdated")
|
||||
.well.pre-line.text-truncate
|
||||
| {{account.note}}
|
||||
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Merges #[span.text-muted ({{merges?.length || 0}})]
|
||||
div
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="refreshDetails()" title="Refresh account details")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
table.table.table-sm(*ngIf="merges?.length")
|
||||
thead
|
||||
tr
|
||||
th id
|
||||
th name
|
||||
th date
|
||||
tbody
|
||||
tr(*ngFor="let m of merges" [class.text-slashed]="m.split")
|
||||
td
|
||||
ng-template(#mergeTooltip)
|
||||
div {{getMergeTooltip(m)}}
|
||||
div([tooltip]="mergeTooltip" placement="right" containerClass="tooltip-merge")
|
||||
| {{m.id}}
|
||||
td {{m.name}}
|
||||
td
|
||||
.d-flex
|
||||
.flex-grow-1
|
||||
time-field([time]="m.date")
|
||||
.dropdown.float-right(dropdown)
|
||||
button.btn.btn-xs.btn-default.dropdown-toggle(
|
||||
dropdownToggle [tooltip]="(m.reason || '[null reason]') + (m.split ? ' (split)' : '')")
|
||||
fa-icon([icon]="cogIcon" [fixedWidth]="true")
|
||||
.dropdown-menu.dropdown-menu-right(*dropdownMenu)
|
||||
button.dropdown-item((click)="printMerge(m)")
|
||||
| Print merge info
|
||||
button.dropdown-item((click)="printMerge2(m)")
|
||||
| Print usable merge info
|
||||
button.dropdown-item((click)="showMergeInNewTab(m)")
|
||||
| Show merge info
|
||||
button.dropdown-item((click)="showMergeInNewTab2(m)")
|
||||
| Show usable merge info
|
||||
.dropdown-divider
|
||||
button.dropdown-item((click)="unmerge(m._id, m.data.merge, m.data.account)")
|
||||
| Split off #[b merged]
|
||||
button.dropdown-item((click)="unmerge(m._id, m.data.account, m.data.merge)")
|
||||
| Split off #[b account]
|
||||
|
||||
h5 Support #[span.text-muted ({{support?.length || 0}})]
|
||||
table.table.table-sm(*ngIf="support?.length")
|
||||
thead
|
||||
tr
|
||||
th message
|
||||
th date
|
||||
tbody
|
||||
tr(*ngFor="let l of support")
|
||||
td
|
||||
fa-icon.mr-1([icon]="l.icon" [ngClass]="l.class")
|
||||
| {{l.message}}
|
||||
td
|
||||
time-field.mr-2([time]="l.date")
|
||||
span.text-muted ({{l.date | date:'MMM d'}})
|
||||
|
||||
h5 Ban log #[span.text-muted ({{banLog?.length || 0}})]
|
||||
table.table.table-sm(*ngIf="banLog?.length")
|
||||
thead
|
||||
tr
|
||||
th message
|
||||
th date
|
||||
tbody
|
||||
tr(*ngFor="let l of banLog")
|
||||
td {{l.message}}
|
||||
td: time-field([time]="l.date")
|
||||
|
||||
.col-md-5
|
||||
//- auths
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Auths #[span.text-muted ({{auths.length}})]
|
||||
.dropdown(dropdown)
|
||||
button.btn.btn-xs.btn-default.dropdown-toggle(dropdownToggle)
|
||||
fa-icon([icon]="cogIcon" [fixedWidth]="true")
|
||||
.dropdown-menu.dropdown-menu-right(*dropdownMenu)
|
||||
a.dropdown-item((click)="fetchAuths()")
|
||||
| Fetch auths data
|
||||
a.dropdown-item((click)="printAuthList()")
|
||||
| Print auths list
|
||||
a.dropdown-item((click)="printAuthData()")
|
||||
| Print auths data
|
||||
|
||||
.mb-2
|
||||
auth-info-edit(*ngFor="let a of auths | slice:0:authLimit" [authId]="a" [duplicates]="duplicates")
|
||||
|
||||
a.text-muted((click)="authLimit = 99999" *ngIf="authLimit < auths.length")
|
||||
| more ...
|
||||
|
||||
.well.mt-2.mb-1.py-2(*ngIf="authData" style="font-size: 12px;")
|
||||
button.close((click)="clearAuthData()" style="color: #ddd; margin-right: -5px; margin-top: -5px;") ×
|
||||
button.close((click)="copyAuthData()" style="color: #ddd; margin-right: 6px; margin-top: -5px;")
|
||||
fa-icon([icon]="copyIcon" size="xs")
|
||||
.text-muted Auths for {{authDataAccount}}
|
||||
.pre-line {{authData}}
|
||||
|
||||
//- origins
|
||||
.d-flex.justify-content-between
|
||||
h5 Origins #[span.text-muted ({{origins.length}})]
|
||||
div
|
||||
button.btn.btn-xs.btn-default((click)="clearOrigins(true, true)" title="Remove all origins older than 14 days used by only one account")
|
||||
fa-icon.mr-1([icon]="trashIcon")
|
||||
| old single
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="clearOrigins(true, false)" title="Remove all origins older than 14 days")
|
||||
fa-icon.mr-1([icon]="trashIcon")
|
||||
| old
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="clearOrigins(false, true)" title="Remove all origins used by only one account")
|
||||
fa-icon.mr-1([icon]="trashIcon")
|
||||
| single
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="clearOrigins(false, false)" title="Remove all origins")
|
||||
fa-icon.mr-1([icon]="trashIcon")
|
||||
| all
|
||||
.dropdown.d-inline-block.ml-1(dropdown)
|
||||
button.btn.btn-xs.btn-default.dropdown-toggle(dropdownToggle title="Remove all origins in region")
|
||||
fa-icon.mr-1([icon]="trashIcon")
|
||||
| region
|
||||
.dropdown-menu(*dropdownMenu)
|
||||
a.dropdown-item(*ngFor="let region of originRegions" (click)="clearOriginsInRegion(region)")
|
||||
| {{region}}
|
||||
.mb-2
|
||||
.d-flex.align-items-center.mb-1(*ngFor="let o of origins")
|
||||
origin-info-remote.flex-grow-1([originIP]="o.ip")
|
||||
small.text-muted
|
||||
from-now.mr-1([time]="o.last")
|
||||
button.btn.btn-xs.btn-default((click)="removeOrigin(o.ip)" title="Remove origin")
|
||||
fa-icon([icon]="trashIcon")
|
||||
|
||||
hr
|
||||
|
||||
//- duplicates
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5
|
||||
| Duplicates #[span.text-muted ({{duplicates?.length}})]
|
||||
fa-icon.text-muted.ml-1(*ngIf="loadingDuplicates" [icon]="spinnerIcon" [fixedWidth]="true" [spin]="true")
|
||||
div
|
||||
button.btn.btn-xs.btn-default((click)="clearOriginsFromDuplicates()" title="Remove all origins older than 14 days from all duplicates")
|
||||
fa-icon.mr-1([icon]="trashIcon")
|
||||
| old
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="refresh()" title="Refresh duplicates")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
.mb-2
|
||||
.text-muted(*ngIf="!duplicates || !duplicates.length")
|
||||
| - no duplicates -
|
||||
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let d of duplicates | slice:0:duplicatesLimit")
|
||||
ng-template(#duplicatePonies)
|
||||
.text-left(*ngIf="d.ponies")
|
||||
div(*ngFor="let p of d.ponies")
|
||||
| {{p}}
|
||||
|
||||
span.badge.badge-none(title="Duplicate origins" [class.deleted]="d.origins === 0")
|
||||
| {{d.origins}}
|
||||
span.badge.badge-none.ml-1(
|
||||
title="Duplicate ponies" [class.deleted]="!d.ponies || !d.ponies.length"
|
||||
[tooltip]="duplicatePonies" [isDisabled]="!d.ponies || !d.ponies.length")
|
||||
| {{d.ponies ? d.ponies.length : '-'}}
|
||||
|
||||
fa-icon.ml-1.text-alert(
|
||||
*ngIf="d.note" [icon]="duplicateNoteIcon" title="Duplicate in note")
|
||||
fa-icon.ml-1.text-muted(
|
||||
*ngIf="d.browserId" [icon]="duplicateBrowserIdIcon" title="Duplicate browser ID")
|
||||
fa-icon.ml-1.text-muted(
|
||||
*ngIf="d.userAgent" [icon]="duplicateBrowserIcon" [tooltip]="d.userAgent" title="Duplicate browser")
|
||||
fa-icon.ml-1(
|
||||
*ngIf="d.emails" [icon]="duplicateEmailIcon" title="Duplicate emails: {{d.emails}}"
|
||||
[ngClass]="d.indenticalEmail ? 'text-alert' : 'text-muted'")
|
||||
fa-icon.ml-1.text-alert(*ngIf="d.birthdate" [icon]="duplicateBirthdateIcon" title="Duplicate birthdate")
|
||||
fa-icon.ml-1.text-muted(*ngIf="d.name" [icon]="duplicateNameIcon" title="Duplicate name")
|
||||
|
||||
account-info-remote.ml-1(#info [accountId]="d.account" [extendedAuths]="true")
|
||||
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="merge(d.account)" title="Merge account")
|
||||
fa-icon([icon]="mergeIcon" size="lg")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="chatLog.add(info.account)" title="Add to chat log")
|
||||
fa-icon([icon]="commentIcon" [fixedWidth]="true")
|
||||
|
||||
a.text-muted(*ngIf="duplicates && duplicates.length > duplicatesLimit" (click)="duplicatesLimit = 9999999")
|
||||
| more ...
|
||||
a.text-muted(*ngIf="duplicates && duplicatesLimit === 9999999" (click)="duplicatesLimit = 10")
|
||||
| less ...
|
||||
|
||||
hr
|
||||
|
||||
//- around
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Around #[span.text-muted ({{around ? around.length : '-'}})]
|
||||
button.btn.btn-xs.btn-default((click)="refreshAround()" title="Refresh around")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of around")
|
||||
span.badge.badge-none(title="Distance in tiles from user") {{a.distance.toFixed(1)}}
|
||||
|
||||
fa-icon.ml-1.text-alert(*ngIf="a.party" [icon]="partyIcon" title="In party with user")
|
||||
|
||||
account-info-remote.ml-1(#info [accountId]="a.account" [extendedAuths]="true" [showDuplicates]="true")
|
||||
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="merge(a.account)" title="Merge account")
|
||||
fa-icon([icon]="mergeIcon" size="lg")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="chatLog.add(info.account)" title="Add to chat log")
|
||||
fa-icon([icon]="commentIcon" [fixedWidth]="true")
|
||||
|
||||
hr
|
||||
|
||||
//- friends
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Friends #[span.text-muted ({{friends ? friends.length : '?'}})]
|
||||
button.btn.btn-xs.btn-default((click)="fetchFriends()" title="Fetch friends list")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of friends | slice:0:friendsLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="removeFriend(a)" title="Remove friend")
|
||||
fa-icon([icon]="trashIcon")
|
||||
a.text-muted(*ngIf="friends && friends.length > friendsLimit" (click)="friendsLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
//- supporter invites
|
||||
//- h5 Supporter invites #[span.text-muted ({{invites?.length || 0}})]
|
||||
//- div(*ngIf="invites?.length")
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let i of invites")
|
||||
.text-muted.mr-2 {{i.type}}
|
||||
fa-icon.mr-2([icon]="checkIcon" [ngClass]="i.active ? 'text-success' : 'text-danger'")
|
||||
account-info-remote.ml-1([accountId]="i.target" [extendedAuths]="true")
|
||||
small.text-muted.flex-grow-1.text-right
|
||||
time-field([time]="i.createdAt")
|
||||
|
||||
hr
|
||||
|
||||
//- force hides
|
||||
div(*ngIf="account.hides && account.hides.length")
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Force hidden #[span.text-muted ({{account.hides.length}})]
|
||||
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of account.hides")
|
||||
account-info-remote([accountId]="a")
|
||||
|
||||
hr
|
||||
|
||||
//- hides
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Hidden by #[span.text-muted ({{hiddenBy ? hiddenBy.length : '?'}})]
|
||||
button.btn.btn-xs.btn-default((click)="fetchHidden()" title="Fetch hidden list")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of hiddenBy | slice:0:hiddenByLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
a.text-muted(*ngIf="hiddenBy && hiddenBy.length > hiddenByLimit" (click)="hiddenByLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
h5 Hides users #[span.text-muted ({{hidden ? hidden.length : '?'}})]
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of hidden | slice:0:hiddenLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
a.text-muted(*ngIf="hidden && hidden.length > hiddenLimit" (click)="hiddenLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
//- hides (perma)
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Perma hidden by #[span.text-muted ({{permaHiddenBy ? permaHiddenBy.length : '?'}})]
|
||||
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of permaHiddenBy | slice:0:permaHiddenByLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
a.text-muted(*ngIf="permaHiddenBy && permaHiddenBy.length > permaHiddenByLimit" (click)="permaHiddenByLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
h5 Perma hides users #[span.text-muted ({{permaHidden ? permaHidden.length : '?'}})]
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of permaHidden | slice:0:permaHiddenLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
a.text-muted(*ngIf="permaHidden && permaHidden.length > permaHiddenLimit" (click)="permaHiddenLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
hr
|
||||
|
||||
//- ignores
|
||||
.d-flex.justify-content-between.align-items-start
|
||||
h5 Ignored by #[span.text-muted ({{ignoredBy ? ignoredBy.length : account.ignoresCount}})]
|
||||
button.btn.btn-xs.btn-default((click)="fetchIgnores()" title="Fetch ignores list")
|
||||
fa-icon([icon]="syncIcon" [fixedWidth]="true")
|
||||
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of ignoredBy | slice:0:ignoredByLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="removeIgnore(a._id, account._id)" title="Remove ignore")
|
||||
fa-icon([icon]="trashIcon")
|
||||
a.text-muted(*ngIf="ignoredBy && ignoredBy.length > ignoredByLimit" (click)="ignoredByLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
h5 Ignores users #[span.text-muted ({{ignores ? ignores.length : '?'}})]
|
||||
.mb-2
|
||||
.mb-1.d-flex.align-items-center(*ngFor="let a of ignores | slice:0:ignoresLimit")
|
||||
account-info-remote([accountId]="a")
|
||||
button.btn.btn-xs.btn-default.ml-1((click)="removeIgnore(account._id, a._id)" title="Remove ignore")
|
||||
fa-icon([icon]="trashIcon")
|
||||
a.text-muted(*ngIf="ignores && ignores.length > ignoresLimit" (click)="ignoresLimit = 9999999")
|
||||
| more ...
|
||||
|
||||
.col-md-3
|
||||
//- emails
|
||||
h5.d-flex.justify-content-between
|
||||
div Emails #[span.text-muted ({{account.emails?.length || 0}})]
|
||||
.dropdown(dropdown)
|
||||
button.btn.btn-xs.btn-default.dropdown-toggle(dropdownToggle)
|
||||
fa-icon([icon]="cogIcon" [fixedWidth]="true")
|
||||
.dropdown-menu.dropdown-menu-right(*dropdownMenu)
|
||||
a.dropdown-item((click)="addEmail()")
|
||||
| Add email
|
||||
.mb-2
|
||||
.text-muted(*ngIf="!account.emails?.length")
|
||||
| - no emails -
|
||||
.d-flex.justify-content-between.items-align-center.mb-1(*ngFor="let e of account.emails | orderBy | slice:0:emailLimit")
|
||||
div {{e}}
|
||||
button.btn.btn-xs.btn-default((click)="removeEmail(e)" title="Remove email")
|
||||
fa-icon([icon]="trashIcon")
|
||||
|
||||
a.text-muted((click)="emailLimit = 99999" *ngIf="emailLimit < (account.emails?.length || 0)")
|
||||
| more ...
|
||||
|
||||
//- ponies
|
||||
h5.d-flex.justify-content-between
|
||||
div Ponies #[span.text-muted ({{account.characterCount}})]
|
||||
.dropdown(dropdown)
|
||||
button.btn.btn-xs.btn-default.dropdown-toggle(dropdownToggle)
|
||||
fa-icon([icon]="cogIcon" [fixedWidth]="true")
|
||||
.dropdown-menu.dropdown-menu-right(*dropdownMenu)
|
||||
a.dropdown-item((click)="getPoniesCreators()")
|
||||
| Fetch creator info
|
||||
a.dropdown-item((click)="restoringPonies = true")
|
||||
| Restore ponies
|
||||
a.dropdown-item((click)="removePoniesAboveLimit()")
|
||||
| Remove ponies above limit
|
||||
a.dropdown-item.text-danger((click)="removeAllPonies()")
|
||||
| Remove all ponies
|
||||
.mb-2(*ngIf="restoringPonies")
|
||||
textarea.form-control.mb-1([(ngModel)]="poniesToRestore" placeholder="paste removed pony logs here")
|
||||
textarea.form-control.mb-1([(ngModel)]="poniesToRestoreFilter" placeholder="paste pony ids to use here (optional)")
|
||||
.text-right
|
||||
button.btn.btn-xs.btn-default((click)="poniesToRestore = ''; restoringPonies = false") cancel
|
||||
button.btn.btn-xs.btn-success.ml-1((click)="restorePonies()" [disabled]="!poniesToRestore") restore
|
||||
hr
|
||||
.mb-2
|
||||
pony-list-remote(
|
||||
[accountId]="id" [expanded]="true" [deletable]="true" [highlight]="highlighCharacter" [duplicates]="duplicates")
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
h5 Events
|
||||
events-table([events]="events" (showChat)="chatLog.show(account)")
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
admin-chat-log(#chatLog [canClose]="false" [account]="account")
|
||||
button.btn.btn-sm.btn-default((click)="printJSON()") raw data
|
||||
|
||||
.well.pre(*ngIf="rawData")
|
||||
| {{rawData}}
|
||||
@@ -0,0 +1,17 @@
|
||||
@import 'partials/variables';
|
||||
|
||||
.spoiler-text {
|
||||
background: $body-color;
|
||||
border-radius: 3px;
|
||||
cursor: default;
|
||||
|
||||
&:hover {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.long-text {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@@ -0,0 +1,582 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { remove, uniq } from 'lodash';
|
||||
import {
|
||||
Account, Event, Auth, ROLES, Character, MergeInfo, MergeAccountData, SupporterInvite, accountFlags,
|
||||
OriginInfoBase, DuplicateResult, AroundEntry, LogEntry
|
||||
} from '../../../common/adminInterfaces';
|
||||
import { compareByName, createSupporterChanges, SupporterChange, getTranslationUrl, getAge } from '../../../common/adminUtils';
|
||||
import { hasRole } from '../../../common/accountUtils';
|
||||
import { AdminModel } from '../../services/adminModel';
|
||||
import {
|
||||
faCog, faSync, faLanguage, faTrash, faGlobe, faTerminal, faSpinner,
|
||||
faIdBadge, faEnvelope, faFont, faCompressArrowsAlt, faComment, faSignOutAlt, faUsers, faCheckCircle,
|
||||
faDatabase, faCopy, faCalendar, faExclamationCircle,
|
||||
} from '../../../client/icons';
|
||||
import { flagsToString, includes, flatten, removeItem } from '../../../common/utils';
|
||||
import { Subscription } from '../../../common/interfaces';
|
||||
import { showTextInNewTab } from '../../../client/htmlUtils';
|
||||
|
||||
const defaultLimit = 15;
|
||||
const defaultDuplicatesLimit = 10;
|
||||
const year = (new Date()).getFullYear();
|
||||
|
||||
@Component({
|
||||
selector: 'admin-account-details',
|
||||
templateUrl: 'admin-account-details.pug',
|
||||
styleUrls: ['admin-account-details.scss'],
|
||||
})
|
||||
export class AdminAccountDetails implements OnInit, OnDestroy {
|
||||
readonly cogIcon = faCog;
|
||||
readonly syncIcon = faSync;
|
||||
readonly langIcon = faLanguage;
|
||||
readonly trashIcon = faTrash;
|
||||
readonly signOutIcon = faSignOutAlt;
|
||||
readonly duplicateNoteIcon = faExclamationCircle;
|
||||
readonly duplicateBrowserIcon = faGlobe;
|
||||
readonly duplicateBrowserIdIcon = faIdBadge;
|
||||
readonly duplicateEmailIcon = faEnvelope;
|
||||
readonly duplicateNameIcon = faFont;
|
||||
readonly duplicateBirthdateIcon = faCalendar;
|
||||
readonly mergeIcon = faCompressArrowsAlt;
|
||||
readonly commentIcon = faComment;
|
||||
readonly partyIcon = faUsers;
|
||||
readonly checkIcon = faCheckCircle;
|
||||
readonly consoleIcon = faTerminal;
|
||||
readonly spinnerIcon = faSpinner;
|
||||
readonly dataIcon = faDatabase;
|
||||
readonly copyIcon = faCopy;
|
||||
readonly roles = ROLES;
|
||||
ages = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
|
||||
account?: Account;
|
||||
duplicates?: DuplicateResult[];
|
||||
ponyNames?: string[];
|
||||
ignores?: string[];
|
||||
ignoredBy?: string[];
|
||||
hidden?: string[];
|
||||
hiddenBy?: string[];
|
||||
permaHidden?: string[];
|
||||
permaHiddenBy?: string[];
|
||||
friends?: string[];
|
||||
events?: Event[];
|
||||
merges?: MergeInfo[];
|
||||
banLog?: LogEntry[];
|
||||
support?: SupporterChange[];
|
||||
rawData?: string;
|
||||
invites?: SupporterInvite[];
|
||||
auths: string[] = [];
|
||||
origins: OriginInfoBase[] = [];
|
||||
counters: { key: string; value: any; }[] = [];
|
||||
authLimit = defaultLimit;
|
||||
emailLimit = defaultLimit;
|
||||
loadingDuplicates = false;
|
||||
accountObject?: Account;
|
||||
clearingSessions = false;
|
||||
authData?: string;
|
||||
authDataAccount?: string;
|
||||
restoringPonies = false;
|
||||
poniesToRestore = '';
|
||||
poniesToRestoreFilter = '';
|
||||
friendsLimit = defaultLimit;
|
||||
hiddenByLimit = defaultLimit;
|
||||
hiddenLimit = defaultLimit;
|
||||
permaHiddenByLimit = defaultLimit;
|
||||
permaHiddenLimit = defaultLimit;
|
||||
private id?: string;
|
||||
private aroundMap = new Map<string, AroundEntry[]>();
|
||||
private duplicatesLimits = new Map<string, number>();
|
||||
private ignoresLimits = new Map<string, number>();
|
||||
private ignoredByLimits = new Map<string, number>();
|
||||
private authsSubscription?: Subscription;
|
||||
private accountSubscription?: Subscription;
|
||||
private originsSubscription?: Subscription;
|
||||
constructor(private route: ActivatedRoute, private model: AdminModel) {
|
||||
}
|
||||
get canRemove() {
|
||||
return hasRole(this.model.account, 'superadmin');
|
||||
}
|
||||
get around() {
|
||||
return this.aroundMap.get(this.id || '');
|
||||
}
|
||||
get duplicatesLimit() {
|
||||
return (this.id && this.duplicatesLimits.has(this.id)) ? this.duplicatesLimits.get(this.id)! : defaultDuplicatesLimit;
|
||||
}
|
||||
set duplicatesLimit(value) {
|
||||
if (this.id) {
|
||||
this.duplicatesLimits.set(this.id, value);
|
||||
}
|
||||
}
|
||||
get ignoresLimit() {
|
||||
return (this.id && this.ignoresLimits.has(this.id)) ? this.ignoresLimits.get(this.id)! : defaultLimit;
|
||||
}
|
||||
set ignoresLimit(value) {
|
||||
if (this.id) {
|
||||
this.ignoresLimits.set(this.id, value);
|
||||
}
|
||||
}
|
||||
get ignoredByLimit() {
|
||||
return (this.id && this.ignoredByLimits.has(this.id)) ? this.ignoredByLimits.get(this.id)! : defaultLimit;
|
||||
}
|
||||
set ignoredByLimit(value) {
|
||||
if (this.id) {
|
||||
this.ignoredByLimits.set(this.id, value);
|
||||
}
|
||||
}
|
||||
get originRegions() {
|
||||
return uniq(this.origins.map(o => o.country));
|
||||
}
|
||||
get age() {
|
||||
return (this.account && this.account.birthdate) ? getAge(this.account.birthdate) : '-';
|
||||
}
|
||||
get forceAge() {
|
||||
return (this.account && this.account.birthyear) ? (year - this.account.birthyear) : '-';
|
||||
}
|
||||
ngOnInit() {
|
||||
this.route.params.subscribe(({ id }) => {
|
||||
this.id = id;
|
||||
this.update();
|
||||
});
|
||||
|
||||
this.model.updated = () => this.update();
|
||||
this.update();
|
||||
}
|
||||
ngOnDestroy() {
|
||||
this.model.updated = () => { };
|
||||
this.authsSubscription && this.authsSubscription.unsubscribe();
|
||||
this.accountSubscription && this.accountSubscription.unsubscribe();
|
||||
this.originsSubscription && this.originsSubscription.unsubscribe();
|
||||
}
|
||||
refresh() {
|
||||
const account = this.account;
|
||||
|
||||
this.ponyNames = [];
|
||||
this.banLog = undefined;
|
||||
this.merges = undefined;
|
||||
this.support = undefined;
|
||||
this.invites = undefined;
|
||||
this.accountObject = undefined;
|
||||
this.loadingDuplicates = false;
|
||||
|
||||
this.authsSubscription && this.authsSubscription.unsubscribe();
|
||||
this.authsSubscription = undefined;
|
||||
|
||||
this.originsSubscription && this.originsSubscription.unsubscribe();
|
||||
this.originsSubscription = undefined;
|
||||
|
||||
this.auths = [];
|
||||
this.origins = [];
|
||||
this.counters = [];
|
||||
|
||||
this.friends = undefined;
|
||||
this.hidden = undefined;
|
||||
this.hiddenBy = undefined;
|
||||
this.permaHidden = undefined;
|
||||
this.permaHiddenBy = undefined;
|
||||
|
||||
if (account) {
|
||||
account.ignoredByLimit = account.ignoredByLimit || 10;
|
||||
account.ignoresLimit = account.ignoresLimit || 10;
|
||||
account.duplicatesLimit = account.duplicatesLimit || 10;
|
||||
|
||||
this.loadingDuplicates = true;
|
||||
this.model.getAllDuplicates(account._id)
|
||||
.then(duplicates => {
|
||||
if (duplicates) {
|
||||
this.ponyNames = uniq(flatten(duplicates.map(d => (d.ponies || []).map(x => x.toLowerCase()))));
|
||||
this.duplicates = duplicates;
|
||||
this.loadingDuplicates = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.model.getAccount(account._id)
|
||||
.then(account => this.accountObject = account);
|
||||
|
||||
this.refreshDetails();
|
||||
|
||||
this.authsSubscription = this.model.accountAuths
|
||||
.subscribe(account._id, auths => this.auths = auths || []);
|
||||
|
||||
this.originsSubscription = this.model.accountOrigins
|
||||
.subscribe(account._id, origins => this.origins = origins || []);
|
||||
} else {
|
||||
this.duplicates = [];
|
||||
this.ignores = [];
|
||||
this.ignoredBy = [];
|
||||
}
|
||||
}
|
||||
refreshAround() {
|
||||
const account = this.account;
|
||||
|
||||
if (account) {
|
||||
this.model.getAccountAround(account._id)
|
||||
.then(accounts => {
|
||||
if (accounts) {
|
||||
this.aroundMap.set(account._id, accounts);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
refreshDetails() {
|
||||
function createCounter(key: string, value: any) {
|
||||
if (key === 'toys') {
|
||||
value = (value >>> 0).toString(2).padStart(32, '0');
|
||||
}
|
||||
|
||||
return { key, value };
|
||||
}
|
||||
|
||||
if (this.account) {
|
||||
this.model.getDetailsForAccount(this.account)
|
||||
.then(details => {
|
||||
if (details) {
|
||||
this.banLog = details.banLog;
|
||||
this.merges = details.merges;
|
||||
this.support = createSupporterChanges(details.supporterLog);
|
||||
this.invites = [
|
||||
...details.invitesSent!.map(i => ({ ...i, type: 'sent' })),
|
||||
...details.invitesReceived!.map(i => ({ ...i, type: 'recv' })),
|
||||
];
|
||||
const state = details.state as any;
|
||||
this.counters = Object.keys(state).map(key => createCounter(key, state[key]));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
fetchIgnores() {
|
||||
if (this.id) {
|
||||
this.model.getIgnoresAndIgnoredBy(this.id)
|
||||
.then(result => {
|
||||
if (result) {
|
||||
this.ignores = result.ignores;
|
||||
this.ignoredBy = result.ignoredBy;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
fetchHidden() {
|
||||
if (this.id) {
|
||||
this.model.getAccountHidden(this.id)
|
||||
.then(result => {
|
||||
if (result) {
|
||||
this.hidden = result.hidden;
|
||||
this.hiddenBy = result.hiddenBy;
|
||||
this.permaHidden = result.permaHidden;
|
||||
this.permaHiddenBy = result.permaHiddenBy;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
fetchFriends() {
|
||||
if (this.id) {
|
||||
this.model.getAccountFriends(this.id)
|
||||
.then(result => this.friends = result);
|
||||
}
|
||||
}
|
||||
removeFriend(friendId: string) {
|
||||
if (this.id && confirm('Are you sure ?')) {
|
||||
this.model.removeFriend(this.id, friendId)
|
||||
.then(() => this.friends && removeItem(this.friends, friendId));
|
||||
}
|
||||
}
|
||||
canToggleRole(role: string) {
|
||||
return role !== 'superadmin' && hasRole(this.model.account, 'superadmin');
|
||||
}
|
||||
hasRole(role: string) {
|
||||
return hasRole(this.account, role);
|
||||
}
|
||||
toggleRole(role: string) {
|
||||
if (this.id) {
|
||||
this.model.setRole(this.id, role, !this.hasRole(role));
|
||||
}
|
||||
}
|
||||
showAccountData() {
|
||||
if (this.id) {
|
||||
this.model.getAccount(this.id)
|
||||
.then(account => {
|
||||
(window as any).$data = account;
|
||||
console.log(account);
|
||||
console.log('accessible in $data');
|
||||
});
|
||||
}
|
||||
}
|
||||
printAuthList() {
|
||||
this.forAuths(auths => {
|
||||
const authList = auths.map((a, i) => `${i + 1}. [${a.provider}] ${a.name || '<no name>'}`).join('\n');
|
||||
this.authData = authList;
|
||||
this.authDataAccount = this.account ? `${this.account.name} [${this.account._id}]` : '';
|
||||
console.log(authList);
|
||||
});
|
||||
}
|
||||
printAuthData() {
|
||||
this.forAuths(auths => {
|
||||
const authData = auths.map((a, i) => `${i + 1}. [${a._id}] [${a.provider}] ${a.name || '<no name>'} (${a.emails})`).join('\n');
|
||||
this.authData = authData;
|
||||
this.authDataAccount = this.account ? `${this.account.name} [${this.account._id}]` : '';
|
||||
console.log(authData);
|
||||
});
|
||||
}
|
||||
copyAuthData() {
|
||||
if ('clipboard' in navigator) {
|
||||
(navigator as any).clipboard.writeText(this.authData);
|
||||
}
|
||||
}
|
||||
clearAuthData() {
|
||||
this.authData = undefined;
|
||||
this.authDataAccount = undefined;
|
||||
}
|
||||
fetchAuths() {
|
||||
this.forAuths(auths => {
|
||||
(window as any).$auths = auths;
|
||||
console.log(auths);
|
||||
});
|
||||
}
|
||||
private forAuths(callback: (auths: Auth[]) => void) {
|
||||
if (this.account) {
|
||||
this.model.getAuthsForAccount(this.account._id)
|
||||
.then(auths => callback(auths || []));
|
||||
}
|
||||
}
|
||||
printJSON() {
|
||||
if (this.id) {
|
||||
this.model.getAccount(this.id)
|
||||
.then(account => this.rawData = JSON.stringify(account, undefined, 2));
|
||||
}
|
||||
}
|
||||
clearOrigins(old: boolean, singles: boolean) {
|
||||
if (this.id) {
|
||||
this.model.clearOriginsForAccount(this.id, { old, singles })
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
}
|
||||
clearOriginsInRegion(country: string) {
|
||||
if (this.id) {
|
||||
this.model.clearOriginsForAccount(this.id, { country })
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
}
|
||||
clearOriginsFromDuplicates() {
|
||||
if (this.account) {
|
||||
const duplicates = (this.duplicates || []).slice(0, this.account.duplicatesLimit || 0);
|
||||
const accounts = duplicates.map(d => d.account);
|
||||
this.model.clearOriginsForAccounts(accounts, { old: true })
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
}
|
||||
removeOrigin(ip: string) {
|
||||
if (this.id) {
|
||||
this.model.removeOriginsForAccount(this.id, [ip])
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
}
|
||||
merge(accountId: string) {
|
||||
if (this.account && confirm('Are you sure?')) {
|
||||
this.model.mergeAccounts(this.account._id, accountId)
|
||||
.then(() => remove(this.duplicates || [], d => d.account === accountId))
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
}
|
||||
remove() {
|
||||
if (this.account && confirm('Are you sure?')) {
|
||||
this.model.removeAccount(this.account._id);
|
||||
}
|
||||
}
|
||||
translateUrl(text: string) {
|
||||
return getTranslationUrl(text);
|
||||
}
|
||||
getPoniesCreators() {
|
||||
if (this.account) {
|
||||
this.model.getPoniesCreators(this.account._id)
|
||||
.then(items => {
|
||||
if (items) {
|
||||
items.sort(compareByName);
|
||||
(window as any).$ponies = items;
|
||||
console.log(items.map(i => `[${i._id}] "${i.name}" ${i.creator}`).join('\n'));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
removePoniesAboveLimit() {
|
||||
if (this.account && confirm('Are you sure?')) {
|
||||
this.model.removePoniesAboveLimit(this.account._id);
|
||||
}
|
||||
}
|
||||
removeAllPonies() {
|
||||
if (this.account && confirm('Are you sure?')) {
|
||||
this.model.removeAllPonies(this.account._id);
|
||||
}
|
||||
}
|
||||
restorePonies() {
|
||||
if (this.account && this.poniesToRestore) {
|
||||
let ids: string[] | undefined = undefined;
|
||||
|
||||
if (this.poniesToRestoreFilter) {
|
||||
const matches = Array.from(this.poniesToRestoreFilter.match(/\[[a-f0-9]{24}\]/g) || [])
|
||||
.map(id => id.substr(1, 24));
|
||||
|
||||
if (matches.length) {
|
||||
ids = matches;
|
||||
}
|
||||
}
|
||||
|
||||
this.model.restorePonies(this.account._id, this.poniesToRestore, ids);
|
||||
this.poniesToRestore = '';
|
||||
this.restoringPonies = false;
|
||||
}
|
||||
}
|
||||
removeEmail(email: string) {
|
||||
if (this.account && confirm('Are you sure?')) {
|
||||
this.model.removeEmail(this.account._id, email);
|
||||
}
|
||||
}
|
||||
removeIgnore(account: string, ignoredAccount: string) {
|
||||
this.model.removeIgnore(account, ignoredAccount)
|
||||
.then(() => this.fetchIgnores());
|
||||
}
|
||||
highlighCharacter = (char: Character | undefined): boolean => {
|
||||
return !!char && includes(this.ponyNames, char.name.toLowerCase());
|
||||
}
|
||||
clearSessions() {
|
||||
if (this.account) {
|
||||
this.clearingSessions = true;
|
||||
this.model.clearSessions(this.account._id)
|
||||
.finally(() => this.clearingSessions = false);
|
||||
}
|
||||
}
|
||||
getMergeTooltip(merge: MergeInfo) {
|
||||
function mergeInfo(title: string, account: MergeAccountData) {
|
||||
return [
|
||||
title,
|
||||
`\tname: ${account.name}`,
|
||||
`\tnote: ${account.note || ''}`,
|
||||
`\tflags: ${flagsToString(account.flags, accountFlags)}`,
|
||||
`\tage: ${account.birthdate ? getAge(account.birthdate) : '-'}`,
|
||||
`\tfriends: ${account.friends ? account.friends.length : 0}`,
|
||||
`\tcounters:`,
|
||||
...Object.keys(account.counters || {}).sort().map(key => `\t\t${key}: ${(account.counters as any)[key]}`),
|
||||
`\tstate:`,
|
||||
...(account.state ? JSON.stringify(account.state, null, 2).split(/\n/).map(x => `\t\t${x}`) : []),
|
||||
`\temails:`,
|
||||
...account.emails.map(e => `\t\t${e}`),
|
||||
`\tauths:`,
|
||||
...account.auths.map(a => `\t\t[${a.id}] ${a.name}`),
|
||||
`\tcharacters: ${account.characters.length}`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
if (merge.data) {
|
||||
return `${mergeInfo('ACCOUNT', merge.data.account)}\n\n${mergeInfo('MERGED', merge.data.merge)}`;
|
||||
} else {
|
||||
return '<empty>';
|
||||
}
|
||||
}
|
||||
printMerge(merge: MergeInfo) {
|
||||
console.log(this.mergeInfo(merge));
|
||||
}
|
||||
printMerge2(merge: MergeInfo) {
|
||||
console.log(this.mergeInfo2(merge));
|
||||
}
|
||||
mergeInfo(merge: MergeInfo) {
|
||||
function mergeInfo(title: string, account: MergeAccountData) {
|
||||
return [
|
||||
title,
|
||||
`\tname: ${account.name}`,
|
||||
`\tnote: ${account.note || ''}`,
|
||||
`\tflags: ${flagsToString(account.flags, accountFlags)}`,
|
||||
`\tage: ${account.birthdate ? getAge(account.birthdate) : '-'}`,
|
||||
`\tcounters:`,
|
||||
...Object.keys(account.counters || {}).sort().map(key => `\t\t${key}: ${(account.counters as any)[key]}`),
|
||||
`\tstate:`,
|
||||
...(account.state ? JSON.stringify(account.state, null, 2).split(/\n/).map(x => `\t\t${x}`) : []),
|
||||
`\temails:`,
|
||||
...account.emails.map(e => `\t\t${e}`),
|
||||
`\tauths:`,
|
||||
...account.auths.map(a => `\t\t[${a.id}] ${a.name}`),
|
||||
`\tcharacters:`,
|
||||
...account.characters.map(a => `\t\t[${a.id}] ${a.name}`),
|
||||
`\tfriends:`,
|
||||
...(account.friends || []).map(i => `\t\t[${i}]`),
|
||||
`\tignores:`,
|
||||
...(account.ignores || []).map(i => `\t\t[${i}]`),
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
return merge.data && `${mergeInfo('ACCOUNT', merge.data.account)}\n\n${mergeInfo('MERGED', merge.data.merge)}`;
|
||||
}
|
||||
private mergeInfo2(merge: MergeInfo) {
|
||||
function mergeInfo(title: string, account: MergeAccountData) {
|
||||
return [
|
||||
title,
|
||||
`\tname: ${JSON.stringify(account.name)}`,
|
||||
`\tnote: ${JSON.stringify(account.note)}`,
|
||||
`\tflags: ${JSON.stringify(account.flags)}`,
|
||||
`\tcounters: ${JSON.stringify(account.counters)}`,
|
||||
`\tstate: ${JSON.stringify(account.state)}`,
|
||||
`\temails: ${JSON.stringify(account.emails)}`,
|
||||
`\tauths: ${JSON.stringify(account.auths)}`,
|
||||
`\tcharacters: ${JSON.stringify(account.characters)}`,
|
||||
`\tfriends: ${JSON.stringify(account.friends)}`,
|
||||
`\tignores: ${JSON.stringify(account.ignores)}`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
return merge.data && `${mergeInfo('ACCOUNT', merge.data.account)}\n\n${mergeInfo('MERGED', merge.data.merge)}`;
|
||||
}
|
||||
showMergeInNewTab(merge: MergeInfo) {
|
||||
showTextInNewTab(this.mergeInfo(merge) || '');
|
||||
}
|
||||
showMergeInNewTab2(merge: MergeInfo) {
|
||||
showTextInNewTab(this.mergeInfo2(merge) || '');
|
||||
}
|
||||
unmerge(mergeId: string | undefined, split: MergeAccountData, keep: MergeAccountData) {
|
||||
if (this.account) {
|
||||
this.model.unmergeAccounts(this.account._id, mergeId, split, keep)
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
}
|
||||
setAge(age: number) {
|
||||
if (this.account) {
|
||||
this.model.setAge(this.account._id, age);
|
||||
}
|
||||
}
|
||||
addEmail() {
|
||||
if (this.account) {
|
||||
const email = prompt('enter email');
|
||||
|
||||
if (email && /@/.test(email)) {
|
||||
this.model.addEmail(this.account._id, email);
|
||||
}
|
||||
}
|
||||
}
|
||||
private update() {
|
||||
if (this.id) {
|
||||
this.accountSubscription && this.accountSubscription.unsubscribe();
|
||||
this.accountSubscription = this.id ? this.model.accounts.subscribe(this.id, a => this.setAccount(a)) : undefined;
|
||||
|
||||
this.events = this.model.events
|
||||
.filter(e => e.account === this.id)
|
||||
.slice(0, 10);
|
||||
}
|
||||
}
|
||||
private setAccount(account: Account | undefined) {
|
||||
const theSame = this.account === account || (this.account && account && this.account._id === account._id);
|
||||
this.account = account;
|
||||
|
||||
if (!theSame) {
|
||||
this.duplicates = [];
|
||||
this.ponyNames = [];
|
||||
this.ignores = [];
|
||||
this.ignoredBy = [];
|
||||
this.rawData = undefined;
|
||||
this.authLimit = defaultLimit;
|
||||
this.emailLimit = defaultLimit;
|
||||
this.duplicatesLimit = defaultDuplicatesLimit;
|
||||
this.refresh();
|
||||
this.friendsLimit = defaultLimit;
|
||||
this.hiddenByLimit = defaultLimit;
|
||||
this.hiddenLimit = defaultLimit;
|
||||
this.permaHiddenByLimit = defaultLimit;
|
||||
this.permaHiddenLimit = defaultLimit;
|
||||
(window as any).$account = account;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user