mirror of
https://github.com/mempool/mempool.git
synced 2025-02-22 14:22:44 +01:00
Merge branch 'master' into nymkappa/bugfix/incorrect-log
This commit is contained in:
commit
cc79b2b2a2
187 changed files with 2998 additions and 895 deletions
|
@ -31,6 +31,7 @@
|
|||
"prefer-const": 1,
|
||||
"prefer-rest-params": 1,
|
||||
"quotes": [1, "single", { "allowTemplateLiterals": true }],
|
||||
"semi": 1
|
||||
"semi": 1,
|
||||
"eqeqeq": 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -434,12 +434,14 @@ class NodesApi {
|
|||
SELECT nodes.public_key, CAST(COALESCE(nodes.capacity, 0) as INT) as capacity, CAST(COALESCE(nodes.channels, 0) as INT) as channels,
|
||||
nodes.alias, UNIX_TIMESTAMP(nodes.first_seen) as first_seen, UNIX_TIMESTAMP(nodes.updated_at) as updated_at,
|
||||
geo_names_city.names as city, geo_names_country.names as country,
|
||||
geo_names_iso.names as iso_code, geo_names_subdivision.names as subdivision
|
||||
geo_names_iso.names as iso_code, geo_names_subdivision.names as subdivision,
|
||||
nodes.longitude, nodes.latitude, nodes.as_number, geo_names_isp.names as isp
|
||||
FROM nodes
|
||||
LEFT JOIN geo_names geo_names_country ON geo_names_country.id = nodes.country_id AND geo_names_country.type = 'country'
|
||||
LEFT JOIN geo_names geo_names_city ON geo_names_city.id = nodes.city_id AND geo_names_city.type = 'city'
|
||||
LEFT JOIN geo_names geo_names_iso ON geo_names_iso.id = nodes.country_id AND geo_names_iso.type = 'country_iso_code'
|
||||
LEFT JOIN geo_names geo_names_subdivision on geo_names_subdivision.id = nodes.subdivision_id AND geo_names_subdivision.type = 'division'
|
||||
LEFT JOIN geo_names geo_names_isp on geo_names_isp.id = nodes.as_number AND geo_names_isp.type = 'as_organization'
|
||||
WHERE geo_names_country.id = ?
|
||||
ORDER BY capacity DESC
|
||||
`;
|
||||
|
@ -449,6 +451,7 @@ class NodesApi {
|
|||
rows[i].country = JSON.parse(rows[i].country);
|
||||
rows[i].city = JSON.parse(rows[i].city);
|
||||
rows[i].subdivision = JSON.parse(rows[i].subdivision);
|
||||
rows[i].isp = JSON.parse(rows[i].isp);
|
||||
}
|
||||
return rows;
|
||||
} catch (e) {
|
||||
|
@ -463,7 +466,8 @@ class NodesApi {
|
|||
SELECT nodes.public_key, CAST(COALESCE(nodes.capacity, 0) as INT) as capacity, CAST(COALESCE(nodes.channels, 0) as INT) as channels,
|
||||
nodes.alias, UNIX_TIMESTAMP(nodes.first_seen) as first_seen, UNIX_TIMESTAMP(nodes.updated_at) as updated_at,
|
||||
geo_names_city.names as city, geo_names_country.names as country,
|
||||
geo_names_iso.names as iso_code, geo_names_subdivision.names as subdivision
|
||||
geo_names_iso.names as iso_code, geo_names_subdivision.names as subdivision,
|
||||
nodes.longitude, nodes.latitude
|
||||
FROM nodes
|
||||
LEFT JOIN geo_names geo_names_country ON geo_names_country.id = nodes.country_id AND geo_names_country.type = 'country'
|
||||
LEFT JOIN geo_names geo_names_city ON geo_names_city.id = nodes.city_id AND geo_names_city.type = 'city'
|
||||
|
|
|
@ -21,6 +21,7 @@ class NodesRoutes {
|
|||
.get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/rankings/age', this.$getOldestNodes)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/:public_key/statistics', this.$getHistoricalNodeStats)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/:public_key', this.$getNode)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/group/:name', this.$getNodeGroup)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -33,6 +34,39 @@ class NodesRoutes {
|
|||
}
|
||||
}
|
||||
|
||||
private async $getNodeGroup(req: Request, res: Response) {
|
||||
try {
|
||||
let nodesList;
|
||||
let nodes: any[] = [];
|
||||
switch (config.MEMPOOL.NETWORK) {
|
||||
case 'testnet':
|
||||
nodesList = ['032c7c7819276c4f706a04df1a0f1e10a5495994a7be4c1d3d28ca766e5a2b957b', '025a7e38c2834dd843591a4d23d5f09cdeb77ddca85f673c2d944a14220ff14cf7', '0395e2731a1673ef21d7a16a727c4fc4d4c35a861c428ce2c819c53d2b81c8bd55', '032ab2028c0b614c6d87824e2373529652fd7e4221b4c70cc4da7c7005c49afcf0', '029001b22fe70b48bee12d014df91982eb85ff1bd404ec772d5c83c4ee3e88d2c3', '0212e2848d79f928411da5f2ff0a8c95ec6ccb5a09d2031b6f71e91309dcde63af', '03e871a2229523d34f76e6311ff197cfe7f26c2fbec13554b93a46f4e710c47dab', '032202ec98d976b0e928bd1d91924e8bd3eab07231fc39feb3737b010071073df8', '02fa7c5a948d03d563a9f36940c2205a814e594d17c0042ced242c71a857d72605', '039c14fdec2d958e3d14cebf657451bbd9e039196615785e82c917f274e3fb2205', '033589bbcb233ffc416cefd5437c7f37e9d7cb7942d405e39e72c4c846d9b37f18', '029293110441c6e2eacb57e1255bf6ef05c41a6a676fe474922d33c19f98a7d584'];
|
||||
break;
|
||||
case 'signet':
|
||||
nodesList = ['03ddab321b760433cbf561b615ef62ac7d318630c5f51d523aaf5395b90b751956', '033d92c7bfd213ef1b34c90e985fb5dc77f9ec2409d391492484e57a44c4aca1de', '02ad010dda54253c1eb9efe38b0760657a3b43ecad62198c359c051c9d99d45781', '025196512905b8a3f1597428b867bec63ec9a95e5089eb7dc7e63e2d2691669029', '027c625aa1fbe3768db68ebcb05b53b6dc0ce68b7b54b8900d326d167363e684fe', '03f1629af3101fcc56b7aac2667016be84e3defbf3d0c8719f836c9b41c9a57a43', '02dfb81e2f7a3c4c9e8a51b70ef82b4a24549cc2fab1f5b2fd636501774a918991', '02d01ccf832944c68f10d39006093769c5b8bda886d561b128534e313d729fdb34', '02499ed23027d4698a6904ff4ec1b6085a61f10b9a6937f90438f9947e38e8ea86', '038310e3a786340f2bd7770704c7ccfe560fd163d9a1c99d67894597419d12cbf7', '03e5e9d879b72c7d67ecd483bae023bd33e695bb32b981a4021260f7b9d62bc761', '028d16e1a0ace4c0c0a421536d8d32ce484dfe6e2f726b7b0e7c30f12a195f8cc7'];
|
||||
break;
|
||||
default:
|
||||
nodesList = ['03fbc17549ec667bccf397ababbcb4cdc0e3394345e4773079ab2774612ec9be61', '03da9a8623241ccf95f19cd645c6cecd4019ac91570e976eb0a128bebbc4d8a437', '03ca5340cf85cb2e7cf076e489f785410838de174e40be62723e8a60972ad75144', '0238bd27f02d67d6c51e269692bc8c9a32357a00e7777cba7f4f1f18a2a700b108', '03f983dcabed6baa1eab5b56c8b2e8fdc846ab3fd931155377897335e85a9fa57c', '03e399589533581e48796e29a825839a010036a61b20744fda929d6709fcbffcc5', '021f5288b5f72c42cd0d8801086af7ce09a816d8ee9a4c47a4b436399b26cb601a', '032b01b7585f781420cd4148841a82831ba37fa952342052cec16750852d4f2dd9', '02848036488d4b8fb1f1c4064261ec36151f43b085f0b51bd239ade3ddfc940c34', '02b6b1640fe029e304c216951af9fbefdb23b0bdc9baaf327540d31b6107841fdf', '03694289827203a5b3156d753071ddd5bf92e371f5a462943f9555eef6d2d6606c', '0283d850db7c3e8ea7cc9c4abc7afaab12bbdf72b677dcba1d608350d2537d7d43'];
|
||||
}
|
||||
|
||||
for (let pubKey of nodesList) {
|
||||
try {
|
||||
const node = await nodesApi.$getNode(pubKey);
|
||||
if (node) {
|
||||
nodes.push(node);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||
res.json(nodes);
|
||||
} catch (e) {
|
||||
res.status(500).send(e instanceof Error ? e.message : e);
|
||||
}
|
||||
}
|
||||
|
||||
private async $getNode(req: Request, res: Response) {
|
||||
try {
|
||||
const node = await nodesApi.$getNode(req.params.public_key);
|
||||
|
|
|
@ -6,7 +6,8 @@ class StatisticsApi {
|
|||
public async $getStatistics(interval: string | null = null): Promise<any> {
|
||||
interval = Common.getSqlInterval(interval);
|
||||
|
||||
let query = `SELECT UNIX_TIMESTAMP(added) AS added, channel_count, total_capacity, tor_nodes, clearnet_nodes, unannounced_nodes
|
||||
let query = `SELECT UNIX_TIMESTAMP(added) AS added, channel_count, total_capacity,
|
||||
tor_nodes, clearnet_nodes, unannounced_nodes, clearnet_tor_nodes
|
||||
FROM lightning_stats`;
|
||||
|
||||
if (interval) {
|
||||
|
|
|
@ -124,7 +124,7 @@ async function buildIncompleteChannel(clChannel: any): Promise<ILightningApi.Cha
|
|||
*/
|
||||
function convertPolicy(clChannel: any): ILightningApi.RoutingPolicy {
|
||||
return {
|
||||
time_lock_delta: 0, // TODO
|
||||
time_lock_delta: clChannel.delay,
|
||||
min_htlc: clChannel.htlc_minimum_msat.slice(0, -4),
|
||||
max_htlc_msat: clChannel.htlc_maximum_msat.slice(0, -4),
|
||||
fee_base_msat: clChannel.base_fee_millisatoshi,
|
||||
|
|
3
contributors/WesVleuten.txt
Normal file
3
contributors/WesVleuten.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of September 1, 2022.
|
||||
|
||||
Signed: WesVleuten
|
|
@ -403,7 +403,7 @@ Corresponding `docker-compose.yml` overrides:
|
|||
|
||||
`mempool-config.json`:
|
||||
```
|
||||
"CLN": {
|
||||
"CLIGHTNING": {
|
||||
"SOCKET": ""
|
||||
}
|
||||
```
|
||||
|
@ -412,6 +412,6 @@ Corresponding `docker-compose.yml` overrides:
|
|||
```
|
||||
api:
|
||||
environment:
|
||||
CLN_SOCKET: ""
|
||||
CLIGHTNING_SOCKET: ""
|
||||
...
|
||||
```
|
||||
|
|
|
@ -67,6 +67,22 @@
|
|||
"ENABLED": __BISQ_ENABLED__,
|
||||
"DATA_PATH": "__BISQ_DATA_PATH__"
|
||||
},
|
||||
"LIGHTNING": {
|
||||
"ENABLED": __LIGHTNING_ENABLED__,
|
||||
"BACKEND": "__LIGHTNING_BACKEND__",
|
||||
"STATS_REFRESH_INTERVAL": __LIGHTNING_STATS_REFRESH_INTERVAL__,
|
||||
"GRAPH_REFRESH_INTERVAL": __LIGHTNING_GRAPH_REFRESH_INTERVAL__,
|
||||
"LOGGER_UPDATE_INTERVAL": __LIGHTNING_LOGGER_UPDATE_INTERVAL__,
|
||||
"TOPOLOGY_FOLDER": "__LIGHTNING_TOPOLOGY_FOLDER__"
|
||||
},
|
||||
"LND": {
|
||||
"TLS_CERT_PATH": "__LND_TLS_CERT_PATH__",
|
||||
"MACAROON_PATH": "__LND_MACAROON_PATH__",
|
||||
"REST_API_URL": "__LND_REST_API_URL__"
|
||||
},
|
||||
"CLIGHTNING": {
|
||||
"SOCKET": "__CLIGHTNING_SOCKET__"
|
||||
},
|
||||
"SOCKS5PROXY": {
|
||||
"ENABLED": __SOCKS5PROXY_ENABLED__,
|
||||
"USE_ONION": __SOCKS5PROXY_USE_ONION__,
|
||||
|
|
|
@ -105,7 +105,7 @@ __LND_MACAROON_PATH__=${LND_MACAROON_PATH:=""}
|
|||
__LND_REST_API_URL__=${LND_REST_API_URL:="https://localhost:8080"}
|
||||
|
||||
# CLN
|
||||
__CLN_SOCKET__=${CLN_SOCKET:=""}
|
||||
__CLIGHTNING_SOCKET__=${CLIGHTNING_SOCKET:=""}
|
||||
|
||||
mkdir -p "${__MEMPOOL_CACHE_DIR__}"
|
||||
|
||||
|
@ -132,8 +132,8 @@ sed -i "s!__MEMPOOL_USER_AGENT__!${__MEMPOOL_USER_AGENT__}!g" mempool-config.jso
|
|||
sed -i "s/__MEMPOOL_STDOUT_LOG_MIN_PRIORITY__/${__MEMPOOL_STDOUT_LOG_MIN_PRIORITY__}/g" mempool-config.json
|
||||
sed -i "s/__MEMPOOL_INDEXING_BLOCKS_AMOUNT__/${__MEMPOOL_INDEXING_BLOCKS_AMOUNT__}/g" mempool-config.json
|
||||
sed -i "s/__MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__/${__MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__}/g" mempool-config.json
|
||||
sed -i "s!__MEMPOOL_POOLS_JSON_URL__!${__MEMPOOL_POOLS_JSON_URL__}/g" mempool-config.json
|
||||
sed -i "s!__MEMPOOL_POOLS_JSON_TREE_URL__!${__MEMPOOL_POOLS_JSON_TREE_URL__}/g" mempool-config.json
|
||||
sed -i "s!__MEMPOOL_POOLS_JSON_URL__!${__MEMPOOL_POOLS_JSON_URL__}!g" mempool-config.json
|
||||
sed -i "s!__MEMPOOL_POOLS_JSON_TREE_URL__!${__MEMPOOL_POOLS_JSON_TREE_URL__}!g" mempool-config.json
|
||||
|
||||
sed -i "s/__CORE_RPC_HOST__/${__CORE_RPC_HOST__}/g" mempool-config.json
|
||||
sed -i "s/__CORE_RPC_PORT__/${__CORE_RPC_PORT__}/g" mempool-config.json
|
||||
|
@ -203,6 +203,6 @@ sed -i "s!__LND_MACAROON_PATH__!${__LND_MACAROON_PATH__}!g" mempool-config.json
|
|||
sed -i "s!__LND_REST_API_URL__!${__LND_REST_API_URL__}!g" mempool-config.json
|
||||
|
||||
# CLN
|
||||
sed -i "s!__CLN_SOCKET__!${__CLN_SOCKET__}!g" mempool-config.json
|
||||
sed -i "s!__CLIGHTNING_SOCKET__!${__CLIGHTNING_SOCKET__}!g" mempool-config.json
|
||||
|
||||
node /backend/package/index.js
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"prefer-const": 1,
|
||||
"prefer-rest-params": 1,
|
||||
"quotes": [1, "single", { "allowTemplateLiterals": true }],
|
||||
"semi": 1
|
||||
"semi": 1,
|
||||
"eqeqeq": 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,10 @@ import { Routes, RouterModule } from '@angular/router';
|
|||
import { AppPreloadingStrategy } from './app.preloading-strategy'
|
||||
import { StartComponent } from './components/start/start.component';
|
||||
import { TransactionComponent } from './components/transaction/transaction.component';
|
||||
import { TransactionPreviewComponent } from './components/transaction/transaction-preview.component';
|
||||
import { BlockComponent } from './components/block/block.component';
|
||||
import { BlockAuditComponent } from './components/block-audit/block-audit.component';
|
||||
import { BlockPreviewComponent } from './components/block/block-preview.component';
|
||||
import { AddressComponent } from './components/address/address.component';
|
||||
import { AddressPreviewComponent } from './components/address/address-preview.component';
|
||||
import { MasterPageComponent } from './components/master-page/master-page.component';
|
||||
import { MasterPagePreviewComponent } from './components/master-page-preview/master-page-preview.component';
|
||||
import { AboutComponent } from './components/about/about.component';
|
||||
import { StatusViewComponent } from './components/status-view/status-view.component';
|
||||
import { TermsOfServiceComponent } from './components/terms-of-service/terms-of-service.component';
|
||||
|
@ -346,61 +342,18 @@ let routes: Routes = [
|
|||
},
|
||||
{
|
||||
path: 'preview',
|
||||
component: MasterPagePreviewComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'block/:id',
|
||||
component: BlockPreviewComponent
|
||||
path: '',
|
||||
loadChildren: () => import('./previews.module').then(m => m.PreviewsModule)
|
||||
},
|
||||
{
|
||||
path: 'testnet/block/:id',
|
||||
component: BlockPreviewComponent
|
||||
path: 'testnet',
|
||||
loadChildren: () => import('./previews.module').then(m => m.PreviewsModule)
|
||||
},
|
||||
{
|
||||
path: 'signet/block/:id',
|
||||
component: BlockPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'address/:id',
|
||||
children: [],
|
||||
component: AddressPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'testnet/address/:id',
|
||||
children: [],
|
||||
component: AddressPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'signet/address/:id',
|
||||
children: [],
|
||||
component: AddressPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'tx/:id',
|
||||
children: [],
|
||||
component: TransactionPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'testnet/tx/:id',
|
||||
children: [],
|
||||
component: TransactionPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'signet/tx/:id',
|
||||
children: [],
|
||||
component: TransactionPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'lightning',
|
||||
loadChildren: () => import('./lightning/lightning-previews.module').then(m => m.LightningPreviewsModule)
|
||||
},
|
||||
{
|
||||
path: 'testnet/lightning',
|
||||
loadChildren: () => import('./lightning/lightning-previews.module').then(m => m.LightningPreviewsModule)
|
||||
},
|
||||
{
|
||||
path: 'signet/lightning',
|
||||
loadChildren: () => import('./lightning/lightning-previews.module').then(m => m.LightningPreviewsModule)
|
||||
path: 'signet',
|
||||
loadChildren: () => import('./previews.module').then(m => m.PreviewsModule)
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -643,35 +596,14 @@ if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') {
|
|||
},
|
||||
{
|
||||
path: 'preview',
|
||||
component: MasterPagePreviewComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'block/:id',
|
||||
component: BlockPreviewComponent
|
||||
path: '',
|
||||
loadChildren: () => import('./previews.module').then(m => m.PreviewsModule)
|
||||
},
|
||||
{
|
||||
path: 'testnet/block/:id',
|
||||
component: BlockPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'address/:id',
|
||||
children: [],
|
||||
component: AddressPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'testnet/address/:id',
|
||||
children: [],
|
||||
component: AddressPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'tx/:id',
|
||||
children: [],
|
||||
component: TransactionPreviewComponent
|
||||
},
|
||||
{
|
||||
path: 'testnet/tx/:id',
|
||||
children: [],
|
||||
component: TransactionPreviewComponent
|
||||
path: 'testnet',
|
||||
loadChildren: () => import('./previews.module').then(m => m.PreviewsModule)
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
@ -20,19 +20,7 @@ import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-st
|
|||
import { CapAddressPipe } from './shared/pipes/cap-address-pipe/cap-address-pipe';
|
||||
import { AppPreloadingStrategy } from './app.preloading-strategy';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
BrowserTransferStateModule,
|
||||
AppRoutingModule,
|
||||
HttpClientModule,
|
||||
BrowserAnimationsModule,
|
||||
SharedModule,
|
||||
],
|
||||
providers: [
|
||||
const providers = [
|
||||
ElectrsApiService,
|
||||
StateService,
|
||||
WebsocketService,
|
||||
|
@ -47,7 +35,31 @@ import { AppPreloadingStrategy } from './app.preloading-strategy';
|
|||
CapAddressPipe,
|
||||
AppPreloadingStrategy,
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
BrowserTransferStateModule,
|
||||
AppRoutingModule,
|
||||
HttpClientModule,
|
||||
BrowserAnimationsModule,
|
||||
SharedModule,
|
||||
],
|
||||
providers: providers,
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
@NgModule({})
|
||||
export class MempoolSharedModule{
|
||||
static forRoot(): ModuleWithProviders<MempoolSharedModule> {
|
||||
return {
|
||||
ngModule: AppModule,
|
||||
providers: providers
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { switchMap, filter, catchError } from 'rxjs/operators';
|
||||
import { ParamMap, ActivatedRoute } from '@angular/router';
|
||||
import { Subscription, of } from 'rxjs';
|
||||
import { BisqTransaction } from '../bisq.interfaces';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-address',
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { BisqBlock } from 'src/app/bisq/bisq.interfaces';
|
||||
import { BisqBlock } from '../../bisq/bisq.interfaces';
|
||||
import { Location } from '@angular/common';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { Subscription, of } from 'rxjs';
|
||||
import { switchMap, catchError } from 'rxjs/operators';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-block',
|
||||
|
|
|
@ -3,9 +3,9 @@ import { BisqApiService } from '../bisq-api.service';
|
|||
import { switchMap, map, take, mergeMap, tap } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { BisqBlock, BisqOutput, BisqTransaction } from '../bisq.interfaces';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-blocks',
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { Observable, combineLatest, BehaviorSubject, of } from 'rxjs';
|
||||
import { map, share, switchMap } from 'rxjs/operators';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { Trade } from '../bisq.interfaces';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { Observable, combineLatest, BehaviorSubject, of } from 'rxjs';
|
||||
import { map, share, switchMap } from 'rxjs/operators';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { Trade } from '../bisq.interfaces';
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
|||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { combineLatest, merge, Observable, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { OffersMarket, Trade } from '../bisq.interfaces';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { BisqStats } from '../bisq.interfaces';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-stats',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, ChangeDetectionStrategy, Input, OnChanges } from '@angular/core';
|
||||
import { BisqTransaction } from 'src/app/bisq/bisq.interfaces';
|
||||
import { BisqTransaction } from '../../bisq/bisq.interfaces';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-transaction-details',
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { BisqTransaction } from 'src/app/bisq/bisq.interfaces';
|
||||
import { BisqTransaction } from '../../bisq/bisq.interfaces';
|
||||
import { switchMap, map, catchError } from 'rxjs/operators';
|
||||
import { of, Observable, Subscription } from 'rxjs';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { Block, Transaction } from 'src/app/interfaces/electrs.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Block, Transaction } from '../../interfaces/electrs.interface';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-transaction',
|
||||
|
|
|
@ -4,11 +4,11 @@ import { BisqTransaction, BisqOutput } from '../bisq.interfaces';
|
|||
import { Observable, Subscription } from 'rxjs';
|
||||
import { switchMap, map, tap } from 'rxjs/operators';
|
||||
import { BisqApiService } from '../bisq-api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { IMultiSelectOption, IMultiSelectSettings, IMultiSelectTexts } from 'src/app/components/ngx-bootstrap-multiselect/types'
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { IMultiSelectOption, IMultiSelectSettings, IMultiSelectTexts } from '../../components/ngx-bootstrap-multiselect/types'
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-transactions',
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy, Input, OnChanges } from '@angular/core';
|
||||
import { BisqTransaction } from 'src/app/bisq/bisq.interfaces';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { BisqTransaction } from '../../bisq/bisq.interfaces';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Block } from 'src/app/interfaces/electrs.interface';
|
||||
import { Block } from '../../interfaces/electrs.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-transfers',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -187,8 +187,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="selfhosted-integrations-sponsor">
|
||||
<h3 i18n="about.self-hosted-integrations">Self-Hosted Integrations</h3>
|
||||
<div class="community-integrations-sponsor">
|
||||
<h3 i18n="about.community-integrations">Community Integrations</h3>
|
||||
<div class="wrapper">
|
||||
<a href="https://github.com/getumbrel/umbrel" target="_blank" title="Umbrel">
|
||||
<img class="image" src="/resources/profile/umbrel.png" />
|
||||
|
@ -218,18 +218,24 @@
|
|||
<img class="image" src="/resources/profile/start9.png" />
|
||||
<span>EmbassyOS</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="community-integrations-sponsor">
|
||||
<h3 i18n="about.wallet-integrations">Wallet Integrations</h3>
|
||||
<div class="wrapper">
|
||||
<a href="https://github.com/btcpayserver/btcpayserver" target="_blank" title="BTCPay Server">
|
||||
<img class="image" src="/resources/profile/btcpayserver.svg" />
|
||||
<span>BTCPay</span>
|
||||
</a>
|
||||
<a href="https://github.com/bisq-network/bisq" target="_blank" title="Bisq">
|
||||
<img class="image" src="/resources/profile/bisq_network.png" />
|
||||
<span>Bisq</span>
|
||||
</a>
|
||||
<a href="https://github.com/BlueWallet/BlueWallet" target="_blank" title="BlueWallet">
|
||||
<img class="image" src="/resources/profile/bluewallet.png" />
|
||||
<span>BlueWallet</span>
|
||||
</a>
|
||||
<a href="https://github.com/muun/apollo" target="_blank" title="Muun Wallet">
|
||||
<img class="image" src="/resources/profile/muun.png" />
|
||||
<span>Muun</span>
|
||||
</a>
|
||||
<a href="https://github.com/spesmilo/electrum" target="_blank" title="Electrum Wallet">
|
||||
<img class="image" src="/resources/profile/electrum.jpg" />
|
||||
<img class="image" src="/resources/profile/electrum.png" />
|
||||
<span>Electrum</span>
|
||||
</a>
|
||||
<a href="https://github.com/cryptoadvance/specter-desktop" target="_blank" title="Specter Wallet">
|
||||
|
@ -244,18 +250,14 @@
|
|||
<img class="image" src="/resources/profile/phoenix.jpg" />
|
||||
<span>Phoenix</span>
|
||||
</a>
|
||||
<a href="https://github.com/lnbits/lnbits-legend" target="_blank" title="LNbits">
|
||||
<img class="image" src="/resources/profile/lnbits.svg" />
|
||||
<span>LNBits</span>
|
||||
</a>
|
||||
<a href="https://github.com/layer2tech/mercury-wallet" target="_blank" title="Mercury Wallet">
|
||||
<img class="image" src="/resources/profile/mercury.svg" />
|
||||
<span>Mercury</span>
|
||||
</a>
|
||||
<a href="https://github.com/muun/apollo" target="_blank" title="Muun Wallet">
|
||||
<img class="image" src="/resources/profile/muun.png" />
|
||||
<span>Muun</span>
|
||||
</a>
|
||||
<a href="https://github.com/BlueWallet/BlueWallet" target="_blank" title="BlueWallet">
|
||||
<img class="image" src="/resources/profile/bluewallet.png" />
|
||||
<span>BlueWallet</span>
|
||||
</a>
|
||||
<a href="https://github.com/hsjoberg/blixt-wallet" target="_blank" title="Blixt Wallet">
|
||||
<img class="image" src="/resources/profile/blixt.png" />
|
||||
<span>Blixt</span>
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
.alliances,
|
||||
.enterprise-sponsor,
|
||||
.community-integrations-sponsor,
|
||||
.selfhosted-integrations-sponsor,
|
||||
.maintainers {
|
||||
margin-top: 68px;
|
||||
margin-bottom: 68px;
|
||||
|
@ -117,7 +116,6 @@
|
|||
.community-sponsor,
|
||||
.project-translators,
|
||||
.community-integrations-sponsor,
|
||||
.selfhosted-integrations-sponsor,
|
||||
.maintainers {
|
||||
.wrapper {
|
||||
display: inline-block;
|
||||
|
@ -193,6 +191,6 @@
|
|||
}
|
||||
|
||||
.community-integrations-sponsor {
|
||||
max-width: 830px;
|
||||
max-width: 970px;
|
||||
margin: auto;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@angular/core';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { IBackendInfo } from 'src/app/interfaces/websocket.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { IBackendInfo } from '../../interfaces/websocket.interface';
|
||||
import { Router } from '@angular/router';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ITranslators } from 'src/app/interfaces/node-api.interface';
|
||||
import { ITranslators } from '../../interfaces/node-api.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-about',
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
<a *ngIf="channel; else default" [routerLink]="['/lightning/channel' | relativeUrl, channel.id]">
|
||||
<ng-template [ngIf]="channel" [ngIfElse]="default">
|
||||
<div>
|
||||
<div class="badge-positioner">
|
||||
<a [routerLink]="['/lightning/channel' | relativeUrl, channel.id]">
|
||||
<span
|
||||
*ngIf="label"
|
||||
class="badge badge-pill badge-warning"
|
||||
>{{ label }}</span>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #default>
|
||||
<span
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
.badge {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.badge-positioner {
|
||||
position: absolute;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, ChangeDetectionStrategy, Input, OnChanges } from '@angular/core';
|
||||
import { Vin, Vout } from '../../interfaces/electrs.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { parseMultisigScript } from 'src/app/bitcoin.utils';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { parseMultisigScript } from '../../bitcoin.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-address-labels',
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<div class="box preview-box" *ngIf="address && !error">
|
||||
<h2 class="preview-header" i18n="shared.address">Address</h2>
|
||||
<app-preview-title>
|
||||
<span i18n="shared.address">Address</span>
|
||||
</app-preview-title>
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<div class="row d-flex justify-content-between">
|
||||
|
|
|
@ -3,13 +3,13 @@ import { ActivatedRoute, ParamMap } from '@angular/router';
|
|||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { switchMap, filter, catchError, map, tap } from 'rxjs/operators';
|
||||
import { Address, Transaction } from '../../interfaces/electrs.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { OpenGraphService } from 'src/app/services/opengraph.service';
|
||||
import { AudioService } from 'src/app/services/audio.service';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { OpenGraphService } from '../../services/opengraph.service';
|
||||
import { AudioService } from '../../services/audio.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { of, merge, Subscription, Observable } from 'rxjs';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { AddressInformation } from 'src/app/interfaces/node-api.interface';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { AddressInformation } from '../../interfaces/node-api.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-address-preview',
|
||||
|
|
|
@ -3,13 +3,13 @@ import { ActivatedRoute, ParamMap } from '@angular/router';
|
|||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { switchMap, filter, catchError, map, tap } from 'rxjs/operators';
|
||||
import { Address, Transaction } from '../../interfaces/electrs.interface';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { AudioService } from 'src/app/services/audio.service';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { AudioService } from '../../services/audio.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { of, merge, Subscription, Observable } from 'rxjs';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { AddressInformation } from 'src/app/interfaces/node-api.interface';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { AddressInformation } from '../../interfaces/node-api.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-address',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Location } from '@angular/common';
|
||||
import { Component, HostListener, OnInit, Inject, LOCALE_ID, HostBinding } from '@angular/core';
|
||||
import { Router, NavigationEnd } from '@angular/router';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { OpenGraphService } from 'src/app/services/opengraph.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { OpenGraphService } from '../../services/opengraph.service';
|
||||
import { NgbTooltipConfig } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { moveDec } from 'src/app/bitcoin.utils';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
||||
import { moveDec } from '../../bitcoin.utils';
|
||||
import { AssetsService } from '../../services/assets.service';
|
||||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -3,15 +3,15 @@ import { ActivatedRoute, ParamMap } from '@angular/router';
|
|||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { switchMap, filter, catchError, take } from 'rxjs/operators';
|
||||
import { Asset, Transaction } from '../../interfaces/electrs.interface';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { AudioService } from 'src/app/services/audio.service';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { AudioService } from '../../services/audio.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { of, merge, Subscription, combineLatest } from 'rxjs';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { moveDec } from 'src/app/bitcoin.utils';
|
||||
import { AssetsService } from '../../services/assets.service';
|
||||
import { moveDec } from '../../bitcoin.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-asset',
|
||||
|
|
|
@ -2,8 +2,8 @@ import { Component, OnInit } from '@angular/core';
|
|||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { ApiService } from '../../../services/api.service';
|
||||
import { AssetsService } from '../../../services/assets.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-asset-group',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { ApiService } from '../../../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-assets-featured',
|
||||
|
|
|
@ -4,11 +4,11 @@ import { Router } from '@angular/router';
|
|||
import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { merge, Observable, of, Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
|
||||
import { AssetExtended } from 'src/app/interfaces/electrs.interface';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { AssetExtended } from '../../../interfaces/electrs.interface';
|
||||
import { AssetsService } from '../../../services/assets.service';
|
||||
import { SeoService } from '../../../services/seo.service';
|
||||
import { StateService } from '../../../services/state.service';
|
||||
import { RelativeUrlPipe } from '../../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { AssetsService } from '../../services/assets.service';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { AssetExtended } from 'src/app/interfaces/electrs.interface';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { AssetExtended } from '../../interfaces/electrs.interface';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-assets',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Env, StateService } from '../../services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { LanguageService } from 'src/app/services/language.service';
|
||||
import { EnterpriseService } from 'src/app/services/enterprise.service';
|
||||
import { LanguageService } from '../../services/language.service';
|
||||
import { EnterpriseService } from '../../services/enterprise.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bisq-master-page',
|
||||
|
|
|
@ -2,11 +2,11 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
|||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, switchMap, tap } from 'rxjs/operators';
|
||||
import { BlockAudit, TransactionStripped } from 'src/app/interfaces/node-api.interface';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { detectWebGL } from 'src/app/shared/graphs.utils';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { BlockAudit, TransactionStripped } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { detectWebGL } from '../../shared/graphs.utils';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { BlockOverviewGraphComponent } from '../block-overview-graph/block-overview-graph.component';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -2,16 +2,16 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, O
|
|||
import { EChartsOption } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { selectPowerOfTen } from 'src/app/bitcoin.utils';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { MiningService } from '../../services/mining.service';
|
||||
import { selectPowerOfTen } from '../../bitcoin.utils';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -2,15 +2,15 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit }
|
|||
import { EChartsOption, graphic } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { formatCurrency, formatNumber, getCurrencySymbol } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { MiningService } from '../../services/mining.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FiatShortenerPipe } from 'src/app/shared/pipes/fiat-shortener.pipe';
|
||||
import { FiatShortenerPipe } from '../../shared/pipes/fiat-shortener.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-fees-graph',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="block-overview-graph">
|
||||
<canvas class="block-overview-canvas" [class.clickable]="!!hoverTx" #blockCanvas></canvas>
|
||||
<div class="loader-wrapper" [class.hidden]="!isLoading">
|
||||
<div class="loader-wrapper" [class.hidden]="!isLoading || disableSpinner">
|
||||
<div class="spinner-border ml-3 loading" role="status"></div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, ElementRef, ViewChild, HostListener, Input, Output, EventEmitter, NgZone, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
import { TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { FastVertexArray } from './fast-vertex-array';
|
||||
import BlockScene from './block-scene';
|
||||
import TxSprite from './tx-sprite';
|
||||
|
@ -17,6 +17,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy {
|
|||
@Input() blockLimit: number;
|
||||
@Input() orientation = 'left';
|
||||
@Input() flip = true;
|
||||
@Input() disableSpinner = false;
|
||||
@Output() txClickEvent = new EventEmitter<TransactionStripped>();
|
||||
@Output() readyEvent = new EventEmitter();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FastVertexArray } from './fast-vertex-array';
|
||||
import TxView from './tx-view';
|
||||
import { TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { Position, Square, ViewUpdateParams } from './sprite-types';
|
||||
|
||||
export default class BlockScene {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import TxSprite from './tx-sprite';
|
||||
import { FastVertexArray } from './fast-vertex-array';
|
||||
import { TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { SpriteUpdateParams, Square, Color, ViewUpdateParams } from './sprite-types';
|
||||
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||||
import { feeLevels, mempoolFeeColors } from '../../app.constants';
|
||||
|
||||
const hoverTransitionTime = 300;
|
||||
const defaultHoverColor = hexToColor('1bd8f4');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, ElementRef, ViewChild, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||||
import { Position } from 'src/app/components/block-overview-graph/sprite-types.js';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { Position } from '../../components/block-overview-graph/sprite-types.js';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-overview-tooltip',
|
||||
|
|
|
@ -2,15 +2,15 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, NgZone, O
|
|||
import { EChartsOption } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-prediction-graph',
|
||||
|
|
|
@ -2,15 +2,15 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit }
|
|||
import { EChartsOption, graphic } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { formatCurrency, formatNumber, getCurrencySymbol } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from 'src/app/shared/graphs.utils';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils';
|
||||
import { MiningService } from '../../services/mining.service';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FiatShortenerPipe } from 'src/app/shared/pipes/fiat-shortener.pipe';
|
||||
import { FiatShortenerPipe } from '../../shared/pipes/fiat-shortener.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-rewards-graph',
|
||||
|
|
|
@ -2,14 +2,14 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, H
|
|||
import { EChartsOption} from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { MiningService } from '../../services/mining.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { download, formatterXAxis } from 'src/app/shared/graphs.utils';
|
||||
import { download, formatterXAxis } from '../../shared/graphs.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-sizes-weights-graph',
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
<div class="box preview-box" *ngIf="!error">
|
||||
<h2 class="preview-header" i18n="shared.block-title">Block</h2>
|
||||
<app-preview-title>
|
||||
<span i18n="shared.block-title">Block</span>
|
||||
</app-preview-title>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="row d-flex justify-content-between">
|
||||
<div class="title-wrapper">
|
||||
<div class="row">
|
||||
<div class="block-titles">
|
||||
<h1 class="title">
|
||||
<ng-template [ngIf]="blockHeight === 0"><ng-container i18n="@@2303359202781425764">Genesis</ng-container></ng-template>
|
||||
<ng-template [ngIf]="blockHeight" i18n="shared.block-title">{{ blockHeight }}</ng-template>
|
||||
</h1>
|
||||
<div class="blockhash" *ngIf="blockHash">
|
||||
<h2 class="truncate right">{{ blockHash.slice(0,32) }}</h2>
|
||||
<h2 class="truncate left">{{ blockHash.slice(32) }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="subtitle truncated" [routerLink]="['/block/' | relativeUrl, blockHash]"><span class="first">{{blockHash.slice(0,-4)}}</span><span class="last-four">{{blockHash.slice(-4)}}</span></a>
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<!-- <tr>
|
||||
|
@ -70,6 +75,7 @@
|
|||
[blockLimit]="stateService.blockVSize"
|
||||
[orientation]="'top'"
|
||||
[flip]="false"
|
||||
[disableSpinner]="true"
|
||||
(readyEvent)="onGraphReady()"
|
||||
></app-block-overview-graph>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,47 @@
|
|||
.table {
|
||||
font-size: 32px;
|
||||
margin-top: 6px;
|
||||
margin-top: 36px;
|
||||
}
|
||||
|
||||
.title-wrapper {
|
||||
.block-titles {
|
||||
margin: 0;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
|
||||
.title {
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
margin-right: 30px;
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
.blockhash {
|
||||
width: 0;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-family: Consolas,Liberation Mono,Courier New,monospace;
|
||||
font-size: 32px;
|
||||
text-align: right;
|
||||
|
||||
.truncate {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0;
|
||||
|
||||
&.left {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
|
|
|
@ -4,11 +4,11 @@ import { ElectrsApiService } from '../../services/electrs-api.service';
|
|||
import { switchMap, tap, throttleTime, catchError, shareReplay, startWith, pairwise, filter } from 'rxjs/operators';
|
||||
import { of, Subscription, asyncScheduler } from 'rxjs';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { OpenGraphService } from 'src/app/services/opengraph.service';
|
||||
import { BlockExtended, TransactionStripped } from 'src/app/interfaces/node-api.interface';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { BlockOverviewGraphComponent } from 'src/app/components/block-overview-graph/block-overview-graph.component';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { OpenGraphService } from '../../services/opengraph.service';
|
||||
import { BlockExtended, TransactionStripped } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-preview',
|
||||
|
|
|
@ -6,13 +6,13 @@ import { switchMap, tap, throttleTime, catchError, map, shareReplay, startWith,
|
|||
import { Transaction, Vout } from '../../interfaces/electrs.interface';
|
||||
import { Observable, of, Subscription, asyncScheduler, EMPTY } from 'rxjs';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { BlockExtended, TransactionStripped } from 'src/app/interfaces/node-api.interface';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { BlockOverviewGraphComponent } from 'src/app/components/block-overview-graph/block-overview-graph.component';
|
||||
import { detectWebGL } from 'src/app/shared/graphs.utils';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { BlockExtended, TransactionStripped } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||
import { detectWebGL } from '../../shared/graphs.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { specialBlocks } from 'src/app/app.constants';
|
||||
import { BlockExtended } from 'src/app/interfaces/node-api.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { specialBlocks } from '../../app.constants';
|
||||
import { BlockExtended } from '../../interfaces/node-api.interface';
|
||||
import { Location } from '@angular/common';
|
||||
import { config } from 'process';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-blockchain',
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core';
|
||||
import { BehaviorSubject, combineLatest, concat, Observable, timer } from 'rxjs';
|
||||
import { delayWhen, map, retryWhen, scan, skip, switchMap, tap } from 'rxjs/operators';
|
||||
import { BlockExtended } from 'src/app/interfaces/node-api.interface';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { BlockExtended } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-blocks-list',
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
<span #buttonWrapper [attr.data-tlite]="copiedMessage" style="position: relative;">
|
||||
<ng-template [ngIf]="button" [ngIfElse]="btnLink">
|
||||
<button #btn [attr.data-clipboard-text]="text" [class]="class" type="button" [disabled]="text === ''">
|
||||
<span #buttonWrapper [attr.data-tlite]="copiedMessage" style="position: relative;top: -2px;left: 1px;">
|
||||
<app-svg-images name="clippy" [width]="size === 'small' ? '10' : '13'" viewBox="0 0 1000 1000"></app-svg-images>
|
||||
</span>
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #btnLink>
|
||||
<span #buttonWrapper [attr.data-tlite]="copiedMessage" style="position: relative;">
|
||||
<button #btn class="btn btn-sm btn-link pt-0 {{ leftPadding ? 'padding' : '' }}" [attr.data-clipboard-text]="text">
|
||||
<app-svg-images name="clippy" [width]="size === 'small' ? '10' : '13'" viewBox="0 0 1000 1000"></app-svg-images>
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
</ng-template>
|
||||
|
|
|
@ -11,6 +11,8 @@ import * as tlite from 'tlite';
|
|||
export class ClipboardComponent implements AfterViewInit {
|
||||
@ViewChild('btn') btn: ElementRef;
|
||||
@ViewChild('buttonWrapper') buttonWrapper: ElementRef;
|
||||
@Input() button = false;
|
||||
@Input() class = 'btn btn-secondary ml-1';
|
||||
@Input() size: 'small' | 'normal' = 'normal';
|
||||
@Input() text: string;
|
||||
@Input() leftPadding = true;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Component, Inject, LOCALE_ID, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { selectPowerOfTen } from 'src/app/bitcoin.utils';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { selectPowerOfTen } from '../../bitcoin.utils';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-difficulty-adjustments-table',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Recommendedfees } from 'src/app/interfaces/websocket.interface';
|
||||
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||||
import { Recommendedfees } from '../../interfaces/websocket.interface';
|
||||
import { feeLevels, mempoolFeeColors } from '../../app.constants';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { MempoolInfo } from 'src/app/interfaces/websocket.interface';
|
||||
import { MempoolInfo } from '../../interfaces/websocket.interface';
|
||||
|
||||
interface MempoolBlocksData {
|
||||
blocks: number;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { StateService } from "src/app/services/state.service";
|
||||
import { WebsocketService } from "src/app/services/websocket.service";
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-graphs',
|
||||
|
|
|
@ -2,16 +2,16 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, H
|
|||
import { EChartsOption, graphic } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { selectPowerOfTen } from 'src/app/bitcoin.utils';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { download } from 'src/app/shared/graphs.utils';
|
||||
import { selectPowerOfTen } from '../../bitcoin.utils';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { MiningService } from '../../services/mining.service';
|
||||
import { download } from '../../shared/graphs.utils';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hashrate-chart',
|
||||
|
|
|
@ -2,13 +2,13 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, L
|
|||
import { EChartsOption } from 'echarts';
|
||||
import { Observable } from 'rxjs';
|
||||
import { delay, map, retryWhen, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { poolsColor } from 'src/app/app.constants';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { MiningService } from 'src/app/services/mining.service';
|
||||
import { download } from 'src/app/shared/graphs.utils';
|
||||
import { poolsColor } from '../../app.constants';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { MiningService } from '../../services/mining.service';
|
||||
import { download } from '../../shared/graphs.utils';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { OnChanges } from '@angular/core';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from '../../shared/graphs.utils';
|
||||
import { formatNumber } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { DOCUMENT } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { languages } from 'src/app/app.constants';
|
||||
import { LanguageService } from 'src/app/services/language.service';
|
||||
import { languages } from '../../app.constants';
|
||||
import { LanguageService } from '../../services/language.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-language-selector',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Env, StateService } from '../../services/state.service';
|
||||
import { merge, Observable, of} from 'rxjs';
|
||||
import { LanguageService } from 'src/app/services/language.service';
|
||||
import { EnterpriseService } from 'src/app/services/enterprise.service';
|
||||
import { LanguageService } from '../../services/language.service';
|
||||
import { EnterpriseService } from '../../services/enterprise.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-liquid-master-page',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-loading-indicator',
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
<span *ngSwitchCase="'signet'" class="network signet"><app-svg-images name="signet" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Signet</span>
|
||||
<span *ngSwitchCase="'testnet'" class="network testnet"><app-svg-images name="testnet" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet</span>
|
||||
<span *ngSwitchCase="'bisq'" class="network bisq"><app-svg-images name="bisq" width="35" height="35" viewBox="0 0 75 75" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Bisq</span>
|
||||
<span *ngSwitchCase="'liquid'" class="network liquid"><app-svg-images name="liquid" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Liquid</span>
|
||||
<span *ngSwitchCase="'liquidtestnet'" class="network liquidtestnet"><app-svg-images name="liquidtestnet" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</span>
|
||||
<span *ngSwitchCase="'liquid'" class="network liquid"><app-svg-images name="liquid" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Mainnet</span>
|
||||
<span *ngSwitchCase="'liquidtestnet'" class="network liquidtestnet"><app-svg-images name="liquidtestnet" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet</span>
|
||||
<span *ngSwitchDefault class="network mainnet"><app-svg-images name="bitcoin" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Mainnet</span>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
z-index: 101;
|
||||
line-height: 80px;
|
||||
text-transform: capitalize;
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
|
||||
::ng-deep .title {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable, merge, of } from 'rxjs';
|
||||
import { LanguageService } from 'src/app/services/language.service';
|
||||
import { LanguageService } from '../../services/language.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-master-page-preview',
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<h2 class="preview-header">
|
||||
<ng-container *ngIf="{ val: network$ | async } as network">
|
||||
<ng-container [ngSwitch]="network.val">
|
||||
<span *ngSwitchCase="'bisq'">Bisq </span>
|
||||
<span *ngSwitchCase="'liquid'">Liquid </span>
|
||||
<span *ngSwitchCase="'liquidtestnet'">Liquid </span>
|
||||
<span *ngSwitchDefault>Bitcoin </span>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-content></ng-content>
|
||||
</h2>
|
|
@ -0,0 +1,20 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable, merge, of } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-preview-title',
|
||||
templateUrl: './preview-title.component.html',
|
||||
styleUrls: [],
|
||||
})
|
||||
export class PreviewTitleComponent implements OnInit {
|
||||
network$: Observable<string>;
|
||||
|
||||
constructor(
|
||||
public stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.network$ = merge(of(''), this.stateService.networkChanged$);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { Env, StateService } from '../../services/state.service';
|
||||
import { Observable, merge, of } from 'rxjs';
|
||||
import { LanguageService } from 'src/app/services/language.service';
|
||||
import { EnterpriseService } from 'src/app/services/enterprise.service';
|
||||
import { LanguageService } from '../../services/language.service';
|
||||
import { EnterpriseService } from '../../services/enterprise.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-master-page',
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Component, ComponentRef, ViewChild, HostListener, Input, Output, EventEmitter,
|
||||
OnDestroy, OnChanges, ChangeDetectionStrategy, AfterViewInit } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { MempoolBlockDelta, TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||||
import { BlockOverviewGraphComponent } from 'src/app/components/block-overview-graph/block-overview-graph.component';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { MempoolBlockDelta, TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||
import { Subscription, BehaviorSubject, merge, of } from 'rxjs';
|
||||
import { switchMap, filter } from 'rxjs/operators';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { switchMap, map, tap, filter } from 'rxjs/operators';
|
||||
import { MempoolBlock, TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||||
import { MempoolBlock, TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { Observable, BehaviorSubject } from 'rxjs';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mempool-block',
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, Input } from '@angular/core';
|
||||
import { Subscription, Observable, fromEvent, merge, of, combineLatest, timer } from 'rxjs';
|
||||
import { MempoolBlock } from 'src/app/interfaces/websocket.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { MempoolBlock } from '../../interfaces/websocket.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { take, map, switchMap } from 'rxjs/operators';
|
||||
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||||
import { specialBlocks } from 'src/app/app.constants';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { feeLevels, mempoolFeeColors } from '../../app.constants';
|
||||
import { specialBlocks } from '../../app.constants';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { Location } from '@angular/common';
|
||||
import { DifficultyAdjustment } from 'src/app/interfaces/node-api.interface';
|
||||
import { DifficultyAdjustment } from '../../interfaces/node-api.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mempool-blocks',
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Component, OnInit, Input, Inject, LOCALE_ID, ChangeDetectionStrategy, OnChanges } from '@angular/core';
|
||||
import { VbytesPipe } from 'src/app/shared/pipes/bytes-pipe/vbytes.pipe';
|
||||
import { VbytesPipe } from '../../shared/pipes/bytes-pipe/vbytes.pipe';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { OptimizedMempoolStats } from 'src/app/interfaces/node-api.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { OptimizedMempoolStats } from '../../interfaces/node-api.interface';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { feeLevels, chartColors } from 'src/app/app.constants';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from 'src/app/shared/graphs.utils';
|
||||
import { feeLevels, chartColors } from '../../app.constants';
|
||||
import { download, formatterXAxis, formatterXAxisLabel } from '../../shared/graphs.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mempool-graph',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mining-dashboard',
|
||||
|
|
|
@ -4,15 +4,15 @@ import { ActivatedRoute, Router } from '@angular/router';
|
|||
import { EChartsOption, PieSeriesOption } from 'echarts';
|
||||
import { concat, Observable } from 'rxjs';
|
||||
import { map, share, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { SinglePoolStats } from 'src/app/interfaces/node-api.interface';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { SinglePoolStats } from '../../interfaces/node-api.interface';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StorageService } from '../..//services/storage.service';
|
||||
import { MiningService, MiningStats } from '../../services/mining.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { chartColors, poolsColor } from 'src/app/app.constants';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { download } from 'src/app/shared/graphs.utils';
|
||||
import { isMobile } from 'src/app/shared/common.utils';
|
||||
import { chartColors, poolsColor } from '../../app.constants';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { download } from '../../shared/graphs.utils';
|
||||
import { isMobile } from '../../shared/common.utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pool-ranking',
|
||||
|
|
34
frontend/src/app/components/pool/pool-preview.component.html
Normal file
34
frontend/src/app/components/pool/pool-preview.component.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<div class="box preview-box" *ngIf="poolStats$ | async as poolStats">
|
||||
<app-preview-title>
|
||||
<span i18n="mining.pools">mining pool</span>
|
||||
</app-preview-title>
|
||||
<div class="row d-flex justify-content-between full-width-row">
|
||||
<div class="title-wrapper">
|
||||
<h1 class="title">{{ poolStats.pool.name }}</h1>
|
||||
</div>
|
||||
<div class="logo-wrapper">
|
||||
<img width="62" height="62" src="/resources/mining-pools/default.svg">
|
||||
<img [class.noimg]="!imageLoaded" width="62" height="62" src="{{ poolStats['logo'] }}"
|
||||
(load)="onImageLoad()" (error)="onImageFail()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row full-width-row">
|
||||
<div class="stats">
|
||||
<div class="stat-box">
|
||||
<div class="label" i18n="mining.tags">Tags</div>
|
||||
<div *ngIf="poolStats.pool.regexes.length else nodata" class="data">{{ poolStats.pool.regexes }}</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="label" i18n="mining.hashrate">Hashrate</div>
|
||||
<div class="data">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row hash-chart full-width-row">
|
||||
<div class="chart" echarts [initOpts]="chartInitOptions" [options]="chartOptions" (chartFinished)="onChartReady()"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #nodata>
|
||||
<div>~</div>
|
||||
</ng-template>
|
78
frontend/src/app/components/pool/pool-preview.component.scss
Normal file
78
frontend/src/app/components/pool/pool-preview.component.scss
Normal file
|
@ -0,0 +1,78 @@
|
|||
.stats {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 15px 0;
|
||||
font-size: 32px;
|
||||
overflow: hidden;
|
||||
|
||||
.stat-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
margin-left: 15px;
|
||||
background: #181b2d;
|
||||
padding: 0.75rem;
|
||||
width: 0;
|
||||
flex-grow: 1;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.data {
|
||||
flex-shrink: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 315px;
|
||||
background: #181b2d;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.full-width-row {
|
||||
padding-left: 15px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.logo-wrapper {
|
||||
position: relative;
|
||||
width: 62px;
|
||||
height: 62px;
|
||||
margin-left: 1em;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background: #24273e;
|
||||
|
||||
&.noimg {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .symbol {
|
||||
font-size: 24px;
|
||||
}
|
187
frontend/src/app/components/pool/pool-preview.component.ts
Normal file
187
frontend/src/app/components/pool/pool-preview.component.ts
Normal file
|
@ -0,0 +1,187 @@
|
|||
import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { EChartsOption, graphic } from 'echarts';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, switchMap, catchError } from 'rxjs/operators';
|
||||
import { PoolStat } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { OpenGraphService } from '../../services/opengraph.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pool-preview',
|
||||
templateUrl: './pool-preview.component.html',
|
||||
styleUrls: ['./pool-preview.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class PoolPreviewComponent implements OnInit {
|
||||
formatNumber = formatNumber;
|
||||
poolStats$: Observable<PoolStat>;
|
||||
isLoading = true;
|
||||
imageLoaded = false;
|
||||
lastImgSrc: string = '';
|
||||
|
||||
chartOptions: EChartsOption = {};
|
||||
chartInitOptions = {
|
||||
renderer: 'svg',
|
||||
};
|
||||
|
||||
slug: string = undefined;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) public locale: string,
|
||||
private apiService: ApiService,
|
||||
private route: ActivatedRoute,
|
||||
public stateService: StateService,
|
||||
private seoService: SeoService,
|
||||
private openGraphService: OpenGraphService,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.poolStats$ = this.route.params.pipe(map((params) => params.slug))
|
||||
.pipe(
|
||||
switchMap((slug: any) => {
|
||||
this.isLoading = true;
|
||||
this.imageLoaded = false;
|
||||
this.slug = slug;
|
||||
this.openGraphService.waitFor('pool-hash-' + this.slug);
|
||||
this.openGraphService.waitFor('pool-stats-' + this.slug);
|
||||
this.openGraphService.waitFor('pool-chart-' + this.slug);
|
||||
this.openGraphService.waitFor('pool-img-' + this.slug);
|
||||
return this.apiService.getPoolHashrate$(this.slug)
|
||||
.pipe(
|
||||
switchMap((data) => {
|
||||
this.isLoading = false;
|
||||
this.prepareChartOptions(data.map(val => [val.timestamp * 1000, val.avgHashrate]));
|
||||
this.openGraphService.waitOver('pool-hash-' + this.slug);
|
||||
return [slug];
|
||||
}),
|
||||
catchError(() => {
|
||||
this.isLoading = false;
|
||||
this.openGraphService.fail('pool-hash-' + this.slug);
|
||||
return of([slug]);
|
||||
})
|
||||
);
|
||||
}),
|
||||
switchMap((slug) => {
|
||||
return this.apiService.getPoolStats$(slug).pipe(
|
||||
catchError(() => {
|
||||
this.isLoading = false;
|
||||
this.openGraphService.fail('pool-stats-' + this.slug);
|
||||
return of(null);
|
||||
})
|
||||
);
|
||||
}),
|
||||
map((poolStats) => {
|
||||
if (poolStats == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.seoService.setTitle(poolStats.pool.name);
|
||||
let regexes = '"';
|
||||
for (const regex of poolStats.pool.regexes) {
|
||||
regexes += regex + '", "';
|
||||
}
|
||||
poolStats.pool.regexes = regexes.slice(0, -3);
|
||||
poolStats.pool.addresses = poolStats.pool.addresses;
|
||||
|
||||
if (poolStats.reportedHashrate) {
|
||||
poolStats.luck = poolStats.estimatedHashrate / poolStats.reportedHashrate * 100;
|
||||
}
|
||||
|
||||
this.openGraphService.waitOver('pool-stats-' + this.slug);
|
||||
|
||||
const logoSrc = `/resources/mining-pools/` + poolStats.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
|
||||
if (logoSrc === this.lastImgSrc) {
|
||||
this.openGraphService.waitOver('pool-img-' + this.slug);
|
||||
}
|
||||
this.lastImgSrc = logoSrc;
|
||||
return Object.assign({
|
||||
logo: logoSrc
|
||||
}, poolStats);
|
||||
}),
|
||||
catchError(() => {
|
||||
this.isLoading = false;
|
||||
this.openGraphService.fail('pool-stats-' + this.slug);
|
||||
return of(null);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
prepareChartOptions(data) {
|
||||
let title: object;
|
||||
if (data.length === 0) {
|
||||
title = {
|
||||
textStyle: {
|
||||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: $localize`:@@23555386d8af1ff73f297e89dd4af3f4689fb9dd:Indexing blocks`,
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
};
|
||||
}
|
||||
|
||||
this.chartOptions = {
|
||||
title: title,
|
||||
animation: false,
|
||||
color: [
|
||||
new graphic.LinearGradient(0, 0, 0, 0.65, [
|
||||
{ offset: 0, color: '#F4511E' },
|
||||
{ offset: 0.25, color: '#FB8C00' },
|
||||
{ offset: 0.5, color: '#FFB300' },
|
||||
{ offset: 0.75, color: '#FDD835' },
|
||||
{ offset: 1, color: '#7CB342' }
|
||||
]),
|
||||
'#D81B60',
|
||||
],
|
||||
grid: {
|
||||
left: 15,
|
||||
right: 15,
|
||||
bottom: 15,
|
||||
top: 15,
|
||||
show: false,
|
||||
},
|
||||
xAxis: data.length === 0 ? undefined : {
|
||||
type: 'time',
|
||||
show: false,
|
||||
},
|
||||
yAxis: data.length === 0 ? undefined : [
|
||||
{
|
||||
type: 'value',
|
||||
show: false,
|
||||
},
|
||||
],
|
||||
series: data.length === 0 ? undefined : [
|
||||
{
|
||||
zlevel: 0,
|
||||
name: 'Hashrate',
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data,
|
||||
type: 'line',
|
||||
lineStyle: {
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
onChartReady(): void {
|
||||
this.openGraphService.waitOver('pool-chart-' + this.slug);
|
||||
}
|
||||
|
||||
onImageLoad(): void {
|
||||
this.imageLoaded = true;
|
||||
this.openGraphService.waitOver('pool-img-' + this.slug);
|
||||
}
|
||||
|
||||
onImageFail(): void {
|
||||
this.imageLoaded = false;
|
||||
this.openGraphService.waitOver('pool-img-' + this.slug);
|
||||
}
|
||||
}
|
|
@ -3,12 +3,12 @@ import { ActivatedRoute } from '@angular/router';
|
|||
import { EChartsOption, graphic } from 'echarts';
|
||||
import { BehaviorSubject, Observable, timer } from 'rxjs';
|
||||
import { distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
|
||||
import { BlockExtended, PoolStat } from 'src/app/interfaces/node-api.interface';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { selectPowerOfTen } from 'src/app/bitcoin.utils';
|
||||
import { BlockExtended, PoolStat } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { selectPowerOfTen } from '../../bitcoin.utils';
|
||||
import { formatNumber } from '@angular/common';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pool',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-push-transaction',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, Input, AfterViewInit, ViewChild, ElementRef, ChangeDetectionStrategy } from '@angular/core';
|
||||
import * as QRCode from 'qrcode';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-qrcode',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { concat, Observable } from 'rxjs';
|
||||
import { map, switchMap, tap } from 'rxjs/operators';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-reward-stats',
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="search-box-container mr-2">
|
||||
<input (focus)="focus$.next($any($event).target.value)" (click)="click$.next($any($event).target.value)" formControlName="searchText" type="text" class="form-control" i18n-placeholder="search-form.searchbar-placeholder" placeholder="Search the full Bitcoin ecosystem">
|
||||
|
||||
<app-search-results #searchResults [results]="typeAhead$ | async" [searchTerm]="searchForm.get('searchText').value" (selectedResult)="selectedResult($event)"></app-search-results>
|
||||
<app-search-results #searchResults [results]="typeAhead$ | async" (selectedResult)="selectedResult($event)"></app-search-results>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { Component, OnInit, ChangeDetectionStrategy, EventEmitter, Output, ViewChild, HostListener } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { AssetsService } from '../../services/assets.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable, of, Subject, zip, BehaviorSubject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, switchMap, catchError, map } from 'rxjs/operators';
|
||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { ElectrsApiService } from '../../services/electrs-api.service';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SearchResultsComponent } from './search-results/search-results.component';
|
||||
|
||||
@Component({
|
||||
|
@ -74,6 +74,7 @@ export class SearchFormComponent implements OnInit {
|
|||
switchMap((text) => {
|
||||
if (!text.length) {
|
||||
return of([
|
||||
'',
|
||||
[],
|
||||
{
|
||||
nodes: [],
|
||||
|
@ -84,11 +85,14 @@ export class SearchFormComponent implements OnInit {
|
|||
this.isTypeaheading$.next(true);
|
||||
if (!this.stateService.env.LIGHTNING) {
|
||||
return zip(
|
||||
of(text),
|
||||
this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([]))),
|
||||
[{ nodes: [], channels: [] }]
|
||||
[{ nodes: [], channels: [] }],
|
||||
of(this.regexBlockheight.test(text)),
|
||||
);
|
||||
}
|
||||
return zip(
|
||||
of(text),
|
||||
this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([]))),
|
||||
this.apiService.lightningSearch$(text).pipe(catchError(() => of({
|
||||
nodes: [],
|
||||
|
@ -102,10 +106,12 @@ export class SearchFormComponent implements OnInit {
|
|||
return result[0].map((address: string) => 'B' + address);
|
||||
}
|
||||
return {
|
||||
addresses: result[0],
|
||||
nodes: result[1].nodes,
|
||||
channels: result[1].channels,
|
||||
totalResults: result[0].length + result[1].nodes.length + result[1].channels.length,
|
||||
searchText: result[0],
|
||||
blockHeight: this.regexBlockheight.test(result[0]) ? [parseInt(result[0], 10)] : [],
|
||||
addresses: result[1],
|
||||
nodes: result[2].nodes,
|
||||
channels: result[2].channels,
|
||||
totalResults: result[1].length + result[2].nodes.length + result[2].channels.length,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@ -121,6 +127,8 @@ export class SearchFormComponent implements OnInit {
|
|||
selectedResult(result: any) {
|
||||
if (typeof result === 'string') {
|
||||
this.search(result);
|
||||
} else if (typeof result === 'number') {
|
||||
this.navigate('/block/', result.toString());
|
||||
} else if (result.alias) {
|
||||
this.navigate('/lightning/node/', result.public_key);
|
||||
} else if (result.short_id) {
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
<div class="dropdown-menu show" *ngIf="results" [hidden]="!results.addresses.length && !results.nodes.length && !results.channels.length">
|
||||
<div class="dropdown-menu show" *ngIf="results" [hidden]="!results.blockHeight.length && !results.addresses.length && !results.nodes.length && !results.channels.length">
|
||||
<ng-template [ngIf]="results.blockHeight.length">
|
||||
<div class="card-title">Bitcoin Block Height</div>
|
||||
<button (click)="clickItem(0)" [class.active]="0 === activeIdx" type="button" role="option" class="dropdown-item">
|
||||
Go to "{{ results.searchText }}"
|
||||
</button>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="results.addresses.length">
|
||||
<div class="card-title" *ngIf="stateService.env.LIGHTNING">Bitcoin Addresses</div>
|
||||
<ng-template ngFor [ngForOf]="results.addresses" let-address let-i="index">
|
||||
<button (click)="clickItem(i)" [class.active]="i === activeIdx" type="button" role="option" class="dropdown-item">
|
||||
<ngb-highlight [result]="address | shortenString : isMobile ? 25 : 36" [term]="searchTerm"></ngb-highlight>
|
||||
<button (click)="clickItem(results.blockHeight.length + i)" [class.active]="(results.blockHeight.length + i) === activeIdx" type="button" role="option" class="dropdown-item">
|
||||
<ngb-highlight [result]="address | shortenString : isMobile ? 25 : 36" [term]="results.searchText"></ngb-highlight>
|
||||
</button>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="results.nodes.length">
|
||||
<div class="card-title">Lightning Nodes</div>
|
||||
<ng-template ngFor [ngForOf]="results.nodes" let-node let-i="index">
|
||||
<button (click)="clickItem(results.addresses.length + i)" [class.inactive]="node.status === 0" [class.active]="results.addresses.length + i === activeIdx" [routerLink]="['/lightning/node' | relativeUrl, node.public_key]" type="button" role="option" class="dropdown-item">
|
||||
<ngb-highlight [result]="node.alias" [term]="searchTerm"></ngb-highlight> <span class="symbol">{{ node.public_key | shortenString : 10 }}</span>
|
||||
<button (click)="clickItem(results.blockHeight.length + results.addresses.length + i)" [class.inactive]="node.status === 0" [class.active]="results.blockHeight.length + results.addresses.length + i === activeIdx" [routerLink]="['/lightning/node' | relativeUrl, node.public_key]" type="button" role="option" class="dropdown-item">
|
||||
<ngb-highlight [result]="node.alias" [term]="results.searchText"></ngb-highlight> <span class="symbol">{{ node.public_key | shortenString : 10 }}</span>
|
||||
</button>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="results.channels.length">
|
||||
<div class="card-title">Lightning Channels</div>
|
||||
<ng-template ngFor [ngForOf]="results.channels" let-channel let-i="index">
|
||||
<button (click)="clickItem(results.addresses.length + results.nodes.length + i)" [class.inactive]="channel.status === 2" [class.active]="results.addresses.length + results.nodes.length + i === activeIdx" type="button" role="option" class="dropdown-item">
|
||||
<ngb-highlight [result]="channel.short_id" [term]="searchTerm"></ngb-highlight> <span class="symbol">{{ channel.id }}</span>
|
||||
<button (click)="clickItem(results.blockHeight.length + results.addresses.length + results.nodes.length + i)" [class.inactive]="channel.status === 2" [class.active]="results.blockHeight.length + results.addresses.length + results.nodes.length + i === activeIdx" type="button" role="option" class="dropdown-item">
|
||||
<ngb-highlight [result]="channel.short_id" [term]="results.searchText"></ngb-highlight> <span class="symbol">{{ channel.id }}</span>
|
||||
</button>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { StateService } from '../../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-results',
|
||||
|
@ -8,7 +8,6 @@ import { StateService } from 'src/app/services/state.service';
|
|||
})
|
||||
export class SearchResultsComponent implements OnChanges {
|
||||
@Input() results: any = {};
|
||||
@Input() searchTerm = '';
|
||||
@Output() selectedResult = new EventEmitter();
|
||||
|
||||
isMobile = (window.innerWidth <= 767.98);
|
||||
|
@ -16,12 +15,14 @@ export class SearchResultsComponent implements OnChanges {
|
|||
activeIdx = 0;
|
||||
focusFirst = true;
|
||||
|
||||
constructor(public stateService: StateService) { }
|
||||
constructor(
|
||||
public stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnChanges() {
|
||||
this.activeIdx = 0;
|
||||
if (this.results) {
|
||||
this.resultsFlattened = [...this.results.addresses, ...this.results.nodes, ...this.results.channels];
|
||||
this.resultsFlattened = [...this.results.blockHeight, ...this.results.addresses, ...this.results.nodes, ...this.results.channels];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +48,7 @@ export class SearchResultsComponent implements OnChanges {
|
|||
if (this.resultsFlattened[this.activeIdx]) {
|
||||
this.selectedResult.emit(this.resultsFlattened[this.activeIdx]);
|
||||
} else {
|
||||
this.selectedResult.emit(this.searchTerm);
|
||||
this.selectedResult.emit(this.results.searchText);
|
||||
}
|
||||
this.results = null;
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { specialBlocks } from 'src/app/app.constants';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { specialBlocks } from '../../app.constants';
|
||||
|
||||
@Component({
|
||||
selector: 'app-start',
|
||||
|
|
|
@ -8,10 +8,10 @@ import { OptimizedMempoolStats } from '../../interfaces/node-api.interface';
|
|||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StorageService } from 'src/app/services/storage.service';
|
||||
import { feeLevels, chartColors } from 'src/app/app.constants';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { StorageService } from '../../services/storage.service';
|
||||
import { feeLevels, chartColors } from '../../app.constants';
|
||||
import { MempoolGraphComponent } from '../mempool-graph/mempool-graph.component';
|
||||
import { IncomingTransactionsGraphComponent } from '../incoming-transactions-graph/incoming-transactions-graph.component';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-status-view',
|
||||
|
|
|
@ -35,10 +35,10 @@
|
|||
<path d="M 464.598 86.568 C 452.881 86.568 444.371 78.058 444.371 66.32 C 444.371 54.644 452.881 46.175 464.598 46.175 C 476.254 46.175 484.723 54.644 484.723 66.32 C 484.723 78.058 476.254 86.568 464.598 86.568 Z M 464.598 53.102 C 457.198 53.102 452.018 58.529 452.018 66.32 C 452.018 74.111 457.198 79.538 464.598 79.538 C 471.937 79.538 477.076 74.111 477.076 66.32 C 477.076 58.529 471.958 53.102 464.598 53.102 Z" fill="white"/>
|
||||
<path d="M 499.996 31.148 L 492.391 31.148 L 492.391 86.198 L 499.996 86.198 L 499.996 31.148 Z" fill="white"/>
|
||||
<path d="M124.706 110.25C124.706 118.849 117.772 125.791 109.183 125.791H15.5236C6.93387 125.791 0 118.849 0 110.25V16.4837C0 7.88416 6.98561 0.942383 15.5236 0.942383H109.183C117.772 0.942383 124.706 7.88416 124.706 16.4837V110.25Z" fill="#2E3349"/>
|
||||
<path d="M0 63.5225V110.25C0 118.849 6.98561 125.791 15.5753 125.791H109.183C117.772 125.791 124.758 118.849 124.758 110.25V63.5225H0Z" fill="url('#paint0_linear')"/>
|
||||
<path d="M0 63.5225V110.25C0 118.849 6.98561 125.791 15.5753 125.791H109.183C117.772 125.791 124.758 118.849 124.758 110.25V63.5225H0Z" [attr.fill]="'url(#paint0_linear' + randomId + ')'"/>
|
||||
<path opacity="0.3" d="M109.909 109.11C109.909 111.026 108.615 112.581 107.011 112.581H90.8665C89.2624 112.581 87.9688 111.026 87.9688 109.11V17.6232C87.9688 15.7065 89.2624 14.1523 90.8665 14.1523H107.011C108.615 14.1523 109.909 15.7065 109.909 17.6232V109.11Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="62.3768" y1="36.3949" x2="62.3768" y2="156.837" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient [id]="'paint0_linear' + randomId" x1="62.3768" y1="36.3949" x2="62.3768" y2="156.837" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#AE61FF"/>
|
||||
<stop offset="1" stop-color="#13EFD8"/>
|
||||
</linearGradient>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { WebsocketService } from '../../services/websocket.service';
|
||||
import { OptimizedMempoolStats } from '../../interfaces/node-api.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { SeoService } from '../../services/seo.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { map, scan, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { interval, merge, Observable } from 'rxjs';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, ChangeDetectorRef, OnChanges } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { dates } from 'src/app/shared/i18n/dates';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { dates } from '../../shared/i18n/dates';
|
||||
|
||||
@Component({
|
||||
selector: 'app-time-since',
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue