diff --git a/frontend/.gitignore b/frontend/.gitignore index ac68948fc..380c2a9d7 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -59,3 +59,6 @@ generated-config.js cypress/videos cypress/screenshots +# Base index +src/index.html + diff --git a/frontend/generate-config.js b/frontend/generate-config.js index fa856dd7d..617ab3c0e 100644 --- a/frontend/generate-config.js +++ b/frontend/generate-config.js @@ -21,6 +21,16 @@ try { } } +const indexFilePath = configContent.BASE_MODULE ? 'src/index.' + configContent.BASE_MODULE + '.html' : 'src/index.mempool.html'; + +try { + fs.copyFileSync(indexFilePath, 'src/index.html'); + console.log('Copied ' + indexFilePath + ' to src/index.html'); +} catch (e) { + console.log('Error copying the index file'); + throw new Error(e); +} + try { const packageJson = fs.readFileSync('package.json'); packetJsonVersion = JSON.parse(packageJson).version; diff --git a/frontend/mempool-frontend-config.sample.json b/frontend/mempool-frontend-config.sample.json index 9a1c72282..c737a2538 100644 --- a/frontend/mempool-frontend-config.sample.json +++ b/frontend/mempool-frontend-config.sample.json @@ -8,5 +8,6 @@ "KEEP_BLOCKS_AMOUNT": 8, "NGINX_PROTOCOL": "http", "NGINX_HOSTNAME": "127.0.0.1", - "NGINX_PORT": "80" + "NGINX_PORT": "80", + "BASE_MODULE": "mempool" } diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 91d37f1eb..f7c741c21 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -19,6 +19,7 @@ import { TermsOfServiceComponent } from './components/terms-of-service/terms-of- import { TrademarkPolicyComponent } from './components/trademark-policy/trademark-policy.component'; import { BisqMasterPageComponent } from './components/bisq-master-page/bisq-master-page.component'; import { SponsorComponent } from './components/sponsor/sponsor.component'; +import { LiquidMasterPageComponent } from './components/liquid-master-page/liquid-master-page.component'; let routes: Routes = [ { @@ -298,7 +299,7 @@ const browserWindow = window || {}; // @ts-ignore const browserWindowEnv = browserWindow.__env || {}; -if (browserWindowEnv && browserWindowEnv.OFFICIAL_BISQ_MARKETS) { +if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'bisq') { routes = [{ path: '', component: BisqMasterPageComponent, @@ -306,6 +307,73 @@ if (browserWindowEnv && browserWindowEnv.OFFICIAL_BISQ_MARKETS) { }]; } +if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') { + routes = [{ + path: '', + component: LiquidMasterPageComponent, + children: [ + { + path: '', + component: StartComponent, + children: [ + { + path: '', + component: DashboardComponent + }, + { + path: 'tx/:id', + component: TransactionComponent + }, + { + path: 'block/:id', + component: BlockComponent + }, + { + path: 'mempool-block/:id', + component: MempoolBlockComponent + }, + ], + }, + { + path: 'blocks', + component: LatestBlocksComponent, + }, + { + path: 'graphs', + component: StatisticsComponent, + }, + { + path: 'address/:id', + component: AddressComponent + }, + { + path: 'asset/:id', + component: AssetComponent + }, + { + path: 'assets', + component: AssetsComponent, + }, + { + path: 'api', + component: ApiDocsComponent, + }, + ], + }, + { + path: 'tv', + component: TelevisionComponent + }, + { + path: 'status', + component: StatusViewComponent + }, + { + path: '**', + redirectTo: '' + }]; +} + @NgModule({ imports: [RouterModule.forRoot(routes, { initialNavigation: 'enabled', diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index a5a732b3b..b8cc4d812 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -22,6 +22,7 @@ import { AddressLabelsComponent } from './components/address-labels/address-labe import { MempoolBlocksComponent } from './components/mempool-blocks/mempool-blocks.component'; import { MasterPageComponent } from './components/master-page/master-page.component'; import { BisqMasterPageComponent } from './components/bisq-master-page/bisq-master-page.component'; +import { LiquidMasterPageComponent } from './components/liquid-master-page/liquid-master-page.component'; import { AboutComponent } from './components/about/about.component'; import { TelevisionComponent } from './components/television/television.component'; import { StatisticsComponent } from './components/statistics/statistics.component'; @@ -60,6 +61,7 @@ import { SponsorComponent } from './components/sponsor/sponsor.component'; AboutComponent, MasterPageComponent, BisqMasterPageComponent, + LiquidMasterPageComponent, TelevisionComponent, BlockchainComponent, StartComponent, diff --git a/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.html b/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.html index e42829e13..132384fa9 100644 --- a/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.html +++ b/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.html @@ -17,7 +17,7 @@

- Markets + Markets Bitcoin Markets

diff --git a/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts b/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts index defac305c..402c9b6fb 100644 --- a/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts +++ b/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts @@ -69,7 +69,7 @@ export class BisqDashboardComponent implements OnInit { const newTickers = []; for (const t in tickers) { - if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) { + if (this.stateService.env.BASE_MODULE !== 'bisq') { const pair = t.split('_'); if (pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1) { continue; @@ -106,7 +106,7 @@ export class BisqDashboardComponent implements OnInit { ]) .pipe( map(([trades, markets]) => { - if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) { + if (this.stateService.env.BASE_MODULE !== 'bisq') { trades = trades.filter((trade) => { const pair = trade.market.split('_'); return !(pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1); diff --git a/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html b/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html index 52c604882..ed61c6fd4 100644 --- a/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html +++ b/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html @@ -63,7 +63,7 @@
- Markets + Markets Bitcoin Markets
@@ -105,7 +105,7 @@
- +
Terms of Service diff --git a/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.ts b/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.ts index 9897d1e03..a59ad88a9 100644 --- a/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.ts +++ b/frontend/src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.ts @@ -77,7 +77,7 @@ export class BisqMainDashboardComponent implements OnInit { const newTickers = []; for (const t in tickers) { - if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) { + if (this.stateService.env.BASE_MODULE !== 'bisq') { const pair = t.split('_'); if (pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1) { continue; @@ -114,7 +114,7 @@ export class BisqMainDashboardComponent implements OnInit { ]) .pipe( map(([trades, markets]) => { - if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) { + if (this.stateService.env.BASE_MODULE !== 'bisq') { trades = trades.filter((trade) => { const pair = trade.market.split('_'); return !(pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1); diff --git a/frontend/src/app/components/liquid-master-page/liquid-master-page.component.html b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.html new file mode 100644 index 000000000..2f0bd58f0 --- /dev/null +++ b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.html @@ -0,0 +1,49 @@ + +
+ +
+ +
+ + + +
+ +
diff --git a/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss new file mode 100644 index 000000000..0efb6fec8 --- /dev/null +++ b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss @@ -0,0 +1,135 @@ +li.nav-item.active { + background-color: #653b9c; +} + +fa-icon { + font-size: 1.66em; +} + +.navbar { + z-index: 100; + min-height: 64px; +} + +li.nav-item { + margin: auto 10px; + padding-left: 10px; + padding-right: 10px; +} + +@media (min-width: 992px) { + .navbar { + padding: 0rem 2rem; + } + fa-icon { + font-size: 1.2em; + } + .dropdown-container { + margin-right: 16px; + } + li.nav-item { + margin: auto 0px; + padding: 10px; + } +} + +.navbar-nav { + background: #212121; + bottom: 0; + box-shadow: 0px 0px 15px 0px #000; + flex-direction: row; + left: 0; + justify-content: center; + position: fixed; + width: 100%; + @media (min-width: 992px) { + background: transparent; + box-shadow: none; + position: relative; + width: auto; + } + a { + font-size: 0.8em; + @media (min-width: 375px) { + font-size: 1em; + } + } +} + + +.navbar-collapse { + flex-basis: auto; + justify-content: flex-end; +} + +@media (min-width: 992px) { + .navbar-collapse { + justify-content: space-between; + } +} + +.navbar-brand { + width: 60%; +} + +@media (min-width: 576px) { + .navbar-brand { + width: 140px; + } +} + +nav { + box-shadow: 0px 0px 15px 0px #000; +} + +.connection-badge { + position: absolute; + top: 13px; + left: 0px; + width: 140px; +} + +.badge { + margin: 0 auto; + display: table; +} + +.mainnet.active { + background-color: #653b9c; +} + +.liquid.active { + background-color: #116761; +} + +.testnet.active { + background-color: #1d486f; +} + +.signet.active { + background-color: #6f1d5d; +} + +.dropdown-divider { + border-top: 1px solid #121420; +} + +.dropdown-toggle::after { + vertical-align: 0.1em; +} + +.dropdown-item { + display: flex; + align-items: center; +} + +@media (min-width: 992px) { + .search-form-container { + width: 100%; + max-width: 500px; + padding-left: 15px; + } +} +.navbar-dark .navbar-nav .nav-link { + color: #f1f1f1; +} \ No newline at end of file diff --git a/frontend/src/app/components/liquid-master-page/liquid-master-page.component.ts b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.ts new file mode 100644 index 000000000..93f0ed1af --- /dev/null +++ b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.ts @@ -0,0 +1,30 @@ +import { Component, OnInit } from '@angular/core'; +import { Env, StateService } from '../../services/state.service'; +import { Observable} from 'rxjs'; + +@Component({ + selector: 'app-liquid-master-page', + templateUrl: './liquid-master-page.component.html', + styleUrls: ['./liquid-master-page.component.scss'], +}) +export class LiquidMasterPageComponent implements OnInit { + env: Env; + network$: Observable; + connectionState$: Observable; + navCollapsed = false; + isMobile = window.innerWidth <= 767.98; + officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; + + constructor( + private stateService: StateService, + ) { } + + ngOnInit() { + this.env = this.stateService.env; + this.connectionState$ = this.stateService.connectionState$; + } + + collapse(): void { + this.navCollapsed = !this.navCollapsed; + } +} diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts index 042a0433e..e66cc915a 100644 --- a/frontend/src/app/services/state.service.ts +++ b/frontend/src/app/services/state.service.ts @@ -24,7 +24,7 @@ export interface Env { ITEMS_PER_PAGE: number; KEEP_BLOCKS_AMOUNT: number; OFFICIAL_MEMPOOL_SPACE: boolean; - OFFICIAL_BISQ_MARKETS: boolean; + BASE_MODULE: string; NGINX_PROTOCOL?: string; NGINX_HOSTNAME?: string; NGINX_PORT?: string; @@ -36,7 +36,7 @@ const defaultEnv: Env = { 'TESTNET_ENABLED': false, 'SIGNET_ENABLED': false, 'LIQUID_ENABLED': false, - 'OFFICIAL_BISQ_MARKETS': false, + 'BASE_MODULE': 'mempool', 'BISQ_ENABLED': false, 'BISQ_SEPARATE_BACKEND': false, 'ITEMS_PER_PAGE': 10, @@ -88,11 +88,10 @@ export class StateService { @Inject(PLATFORM_ID) private platformId: any, private router: Router, ) { - this.router.events.subscribe((event) => { - if (event instanceof NavigationStart) { - this.setNetworkBasedonUrl(event.url); - } - }); + const browserWindow = window || {}; + // @ts-ignore + const browserWindowEnv = browserWindow.__env || {}; + this.env = Object.assign(defaultEnv, browserWindowEnv); if (this.isBrowser) { this.setNetworkBasedonUrl(window.location.pathname); @@ -102,15 +101,24 @@ export class StateService { this.isTabHidden$ = new BehaviorSubject(false); } - const browserWindow = window || {}; - // @ts-ignore - const browserWindowEnv = browserWindow.__env || {}; - this.env = Object.assign(defaultEnv, browserWindowEnv); + this.router.events.subscribe((event) => { + if (event instanceof NavigationStart) { + this.setNetworkBasedonUrl(event.url); + } + }); this.blocks$ = new ReplaySubject<[Block, boolean]>(this.env.KEEP_BLOCKS_AMOUNT); + + if (this.env.BASE_MODULE !== 'mempool') { + this.network = this.env.BASE_MODULE; + this.networkChanged$.next(this.env.BASE_MODULE); + } } setNetworkBasedonUrl(url: string) { + if (this.env.BASE_MODULE !== 'mempool') { + return; + } const networkMatches = url.match(/\/(bisq|testnet|liquid|signet)/); switch (networkMatches && networkMatches[1]) { case 'liquid': diff --git a/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.ts b/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.ts index 779268416..a19e93a75 100644 --- a/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.ts +++ b/frontend/src/app/shared/pipes/relative-url/relative-url.pipe.ts @@ -11,6 +11,9 @@ export class RelativeUrlPipe implements PipeTransform { ) { } transform(value: string): string { + if (this.stateService.env.BASE_MODULE !== 'mempool') { + return '/' + value; + } return (this.stateService.network ? '/' + this.stateService.network : '') + value; } diff --git a/frontend/src/index.liquid.html b/frontend/src/index.liquid.html new file mode 100644 index 000000000..5adf45be3 --- /dev/null +++ b/frontend/src/index.liquid.html @@ -0,0 +1,52 @@ + + + + + Liquid Network - Block Explorer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/index.html b/frontend/src/index.mempool.html similarity index 100% rename from frontend/src/index.html rename to frontend/src/index.mempool.html diff --git a/frontend/src/resources/liquid-network-logo.svg b/frontend/src/resources/liquid-network-logo.svg new file mode 100644 index 000000000..4b794f29d --- /dev/null +++ b/frontend/src/resources/liquid-network-logo.svg @@ -0,0 +1,39 @@ + + + brand/logo-products/liquid + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file