Skip to content

Commit d21178c

Browse files
SgtPooki2color
andauthored
feat!: config is always visible on landing page (#496)
* feat!: config is always visible on landing page * chore: remove unused gear-icon.svg * chore: address self pr comments * fix: github CI points to aegir main branch * chore: pr suggestion add comment Co-authored-by: Daniel Norman <[email protected]> --------- Co-authored-by: Daniel Norman <[email protected]>
1 parent 9755b14 commit d21178c

File tree

13 files changed

+80
-67
lines changed

13 files changed

+80
-67
lines changed

.github/workflows/main.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- uses: actions/setup-node@v4
1919
with:
2020
node-version: lts/*
21-
- uses: ipfs/aegir/actions/cache-node-modules@master
21+
- uses: ipfs/aegir/actions/cache-node-modules@main
2222
- name: Save ./dist output for later
2323
uses: actions/upload-artifact@v4
2424
with:
@@ -33,7 +33,7 @@ jobs:
3333
- uses: actions/setup-node@v4
3434
with:
3535
node-version: lts/*
36-
- uses: ipfs/aegir/actions/cache-node-modules@master
36+
- uses: ipfs/aegir/actions/cache-node-modules@main
3737
- run: npm run --if-present lint
3838
- run: npm run --if-present dep-check
3939
- run: npm run --if-present doc-check
@@ -51,7 +51,7 @@ jobs:
5151
- uses: actions/setup-node@v4
5252
with:
5353
node-version: ${{ matrix.node }}
54-
- uses: ipfs/aegir/actions/cache-node-modules@master
54+
- uses: ipfs/aegir/actions/cache-node-modules@main
5555
- run: npm run --if-present test:node
5656
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
5757
with:
@@ -66,7 +66,7 @@ jobs:
6666
- uses: actions/setup-node@v4
6767
with:
6868
node-version: lts/*
69-
- uses: ipfs/aegir/actions/cache-node-modules@master
69+
- uses: ipfs/aegir/actions/cache-node-modules@main
7070
- run: npx playwright install --with-deps
7171
- run: npm run --if-present test:chrome
7272
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
@@ -82,7 +82,7 @@ jobs:
8282
- uses: actions/setup-node@v4
8383
with:
8484
node-version: lts/*
85-
- uses: ipfs/aegir/actions/cache-node-modules@master
85+
- uses: ipfs/aegir/actions/cache-node-modules@main
8686
- run: npm run --if-present test:chrome-webworker
8787
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
8888
with:
@@ -97,7 +97,7 @@ jobs:
9797
- uses: actions/setup-node@v4
9898
with:
9999
node-version: lts/*
100-
- uses: ipfs/aegir/actions/cache-node-modules@master
100+
- uses: ipfs/aegir/actions/cache-node-modules@main
101101
- run: npx playwright install --with-deps
102102
- run: npm run --if-present test:firefox
103103
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
@@ -113,7 +113,7 @@ jobs:
113113
- uses: actions/setup-node@v4
114114
with:
115115
node-version: lts/*
116-
- uses: ipfs/aegir/actions/cache-node-modules@master
116+
- uses: ipfs/aegir/actions/cache-node-modules@main
117117
- run: npm run --if-present test:firefox-webworker
118118
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
119119
with:
@@ -128,7 +128,7 @@ jobs:
128128
- uses: actions/setup-node@v4
129129
with:
130130
node-version: lts/*
131-
- uses: ipfs/aegir/actions/cache-node-modules@master
131+
- uses: ipfs/aegir/actions/cache-node-modules@main
132132
- run: npm run --if-present test:webkit
133133
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
134134
with:
@@ -143,7 +143,7 @@ jobs:
143143
- uses: actions/setup-node@v4
144144
with:
145145
node-version: lts/*
146-
- uses: ipfs/aegir/actions/cache-node-modules@master
146+
- uses: ipfs/aegir/actions/cache-node-modules@main
147147
- run: npx xvfb-maybe npm run --if-present test:electron-main
148148
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
149149
with:
@@ -158,7 +158,7 @@ jobs:
158158
- uses: actions/setup-node@v4
159159
with:
160160
node-version: lts/*
161-
- uses: ipfs/aegir/actions/cache-node-modules@master
161+
- uses: ipfs/aegir/actions/cache-node-modules@main
162162
- run: npx xvfb-maybe npm run --if-present test:electron-renderer
163163
- uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
164164
with:

src/components/About.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22

33
export default function About (): JSX.Element {
44
return (
5-
<aside className='mw7 lb-snow center w-100 lh-copy pa2'>
5+
<aside className='mw7 lb-snow center w-100 lh-copy pa2 e2e-section-about'>
66
<h1 className='pa0 f3 ma0 mb4 teal tc'>About the IPFS Gateway and Service Worker</h1>
77
<p>This page runs an IPFS gateway within a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" target="_blank">Service Worker</a>. It uses <a href="https://github.com/ipfs/helia" target="_blank">Helia</a> (IPFS implementation in JS) and the <a href="https://github.com/ipfs/helia-verified-fetch" target="_blank">@helia/verified-fetch</a> library (<a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" target="_blank">Fetch API</a> for IPFS) to facilitate direct verified retrieval of <a href="https://docs.ipfs.tech/concepts/content-addressing/" target="_blank">content-addressed</a> data.</p>
88
<p><strong>Why?</strong> It improves decentralization, offers enhanced security (CID verification happens on end user's machine) and reliability (ability to do retrieval from multiple sources without reliance on a single HTTP server).</p>

src/components/Header.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import React from 'react'
2-
import { RouteContext } from '../context/router-context.jsx'
3-
import gearIcon from '../gear-icon.svg'
1+
import React, { type FunctionComponent } from 'react'
42
import ipfsLogo from '../ipfs-logo.svg'
53

6-
export default function Header ({ showConfigIcon = false }: { showConfigIcon?: boolean }): JSX.Element {
7-
const { gotoPage } = React.useContext(RouteContext)
4+
export interface HeaderProps extends React.HTMLProps<HTMLElement> {
5+
6+
}
7+
8+
export const Header: FunctionComponent<HeaderProps> = () => {
89
return (
910
<header className='e2e-header flex items-center pa2 bg-navy bb bw3 b--aqua tc justify-between'>
1011
<div>
@@ -14,16 +15,8 @@ export default function Header ({ showConfigIcon = false }: { showConfigIcon?: b
1415
</div>
1516
<div className='pb1 ma0 inline-flex items-center'>
1617
<h1 className='e2e-header-title f3 fw2 aqua ttu sans-serif'>Service Worker Gateway <small className="gray">(beta)</small></h1>
17-
{showConfigIcon && <button className='e2e-header-config-button pl3'
18-
onClick={() => {
19-
gotoPage('/ipfs-sw-config')
20-
}}
21-
style={{ border: 'none', background: 'none', cursor: 'pointer' }}
22-
>
23-
<img alt='Config gear icon' src={gearIcon} style={{ height: 50 }} className='v-top' />
24-
</button>}
2518
</div>
26-
2719
</header>
2820
)
2921
}
22+
export default Header

src/context/config-context.tsx

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
11
import React, { createContext, useCallback, useEffect, useState } from 'react'
22
import { defaultDebug, defaultDnsJsonResolvers, defaultEnableGatewayProviders, defaultEnableRecursiveGateways, defaultEnableWebTransport, defaultEnableWss, defaultGateways, defaultRouters, getConfig, resetConfig, type ConfigDb } from '../lib/config-db.js'
3-
import { isConfigPage } from '../lib/is-config-page.js'
43
import { getUiComponentLogger } from '../lib/logger.js'
54
import type { ComponentLogger } from '@libp2p/logger'
65

7-
const isLoadedInIframe = window.self !== window.top
8-
96
type ConfigKey = keyof ConfigDb
107
export interface ConfigContextType extends ConfigDb {
11-
isConfigExpanded: boolean
12-
setConfigExpanded(value: boolean): void
138
setConfig(key: ConfigKey, value: any): void
149
resetConfig(logger?: ComponentLogger): Promise<void>
1510
}
1611

1712
export const ConfigContext = createContext<ConfigContextType>({
18-
isConfigExpanded: isLoadedInIframe,
1913
setConfigExpanded: (value: boolean) => {},
2014
setConfig: (key, value) => {},
2115
resetConfig: async () => Promise.resolve(),
@@ -30,7 +24,6 @@ export const ConfigContext = createContext<ConfigContextType>({
3024
})
3125

3226
export const ConfigProvider = ({ children }: { children: JSX.Element[] | JSX.Element, expanded?: boolean }): JSX.Element => {
33-
const [isConfigExpanded, setConfigExpanded] = useState(isConfigPage(window.location.hash))
3427
const [gateways, setGateways] = useState<string[]>(defaultGateways)
3528
const [routers, setRouters] = useState<string[]>(defaultRouters)
3629
const [dnsJsonResolvers, setDnsJsonResolvers] = useState<Record<string, string>>(defaultDnsJsonResolvers)
@@ -39,7 +32,6 @@ export const ConfigProvider = ({ children }: { children: JSX.Element[] | JSX.Ele
3932
const [enableGatewayProviders, setEnableGatewayProviders] = useState(defaultEnableGatewayProviders)
4033
const [enableRecursiveGateways, setEnableRecursiveGateways] = useState(defaultEnableRecursiveGateways)
4134
const [debug, setDebug] = useState(defaultDebug)
42-
const isExplicitlyLoadedConfigPage = isConfigPage(window.location.hash)
4335
const logger = getUiComponentLogger('config-context')
4436
const log = logger.forComponent('main')
4537

@@ -103,16 +95,8 @@ export const ConfigProvider = ({ children }: { children: JSX.Element[] | JSX.Ele
10395
await loadConfig()
10496
}
10597

106-
const setConfigExpandedWrapped = (value: boolean): void => {
107-
if (isLoadedInIframe || isExplicitlyLoadedConfigPage) {
108-
// ignore it
109-
} else {
110-
setConfigExpanded(value)
111-
}
112-
}
113-
11498
return (
115-
<ConfigContext.Provider value={{ isConfigExpanded, setConfigExpanded: setConfigExpandedWrapped, setConfig: setConfigLocal, resetConfig: resetConfigLocal, gateways, routers, dnsJsonResolvers, enableWss, enableWebTransport, enableGatewayProviders, enableRecursiveGateways, debug }}>
99+
<ConfigContext.Provider value={{ setConfig: setConfigLocal, resetConfig: resetConfigLocal, gateways, routers, dnsJsonResolvers, enableWss, enableWebTransport, enableGatewayProviders, enableRecursiveGateways, debug }}>
116100
{children}
117101
</ConfigContext.Provider>
118102
)

src/gear-icon.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/lib/is-config-page.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* As of https://github.com/ipfs/service-worker-gateway/issues/486, we no longer have a singular page at
3+
* /#/ipfs-sw-config unless loaded directly from a subdomain. The configuration section is now on the main page (helper-ui.tsx)
4+
*
5+
* We still use /#/ipfs-sw-config to allow subdomain users to change config and we need to detect that.
6+
*/
17
export function isConfigPage (hash: string): boolean {
28
const isConfigHashPath = hash.startsWith('#/ipfs-sw-config') // needed for _redirects and IPFS hosted sw gateways
39
return isConfigHashPath

src/lib/routing-render-checks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ export async function shouldRenderRedirectPage (): Promise<boolean> {
2121

2222
export async function shouldRenderConfigPage (): Promise<boolean> {
2323
const { isConfigPage } = await import('../lib/is-config-page.js')
24+
const { isSubdomainGatewayRequest } = await import('./path-or-subdomain.js')
2425

2526
const isRequestToViewConfigPage = isConfigPage(window.location.hash)
26-
return isRequestToViewConfigPage
27+
return isRequestToViewConfigPage && isSubdomainGatewayRequest(window.location)
2728
}
2829

2930
export function shouldRenderRedirectsInterstitial (): boolean {

src/pages/config.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import React, { useCallback, useContext, useEffect, useState } from 'react'
1+
import React, { useCallback, useContext, useEffect, useState, type FunctionComponent } from 'react'
22
import Header from '../components/Header.jsx'
3-
import { Collapsible } from '../components/collapsible.jsx'
43
import { InputSection } from '../components/input-section.jsx'
54
import { InputToggle } from '../components/input-toggle.jsx'
65
import { ServiceWorkerReadyButton } from '../components/sw-ready-button.jsx'
@@ -10,6 +9,7 @@ import { RouteContext } from '../context/router-context.jsx'
109
import { ServiceWorkerProvider } from '../context/service-worker-context.jsx'
1110
import { setConfig as storeConfig } from '../lib/config-db.js'
1211
import { convertDnsResolverInputToObject, convertDnsResolverObjectToInput, convertUrlArrayToInput, convertUrlInputToArray } from '../lib/input-helpers.js'
12+
import { isConfigPage } from '../lib/is-config-page.js'
1313
import { getUiComponentLogger, uiLogger } from '../lib/logger.js'
1414
import './default-page-styles.css'
1515
import { tellSwToReloadConfig } from '../lib/sw-comms.js'
@@ -75,7 +75,12 @@ const dnsJsonValidationFn = (value: string): Error | null => {
7575
}
7676
}
7777

78-
function ConfigPage (): React.JSX.Element | null {
78+
export interface ConfigPageProps extends React.HTMLProps<HTMLElement> {
79+
80+
}
81+
82+
// Config Page can be loaded either as a page or as a component in the landing helper-ui page
83+
const ConfigPage: FunctionComponent<ConfigPageProps> = () => {
7984
const { gotoPage } = useContext(RouteContext)
8085
const { setConfig, resetConfig, gateways, routers, dnsJsonResolvers, debug, enableGatewayProviders, enableRecursiveGateways, enableWss, enableWebTransport } = useContext(ConfigContext)
8186
const [isSaving, setIsSaving] = useState(false)
@@ -140,9 +145,9 @@ function ConfigPage (): React.JSX.Element | null {
140145

141146
return (
142147
<>
143-
{!isLoadedInIframe && <Header /> }
144-
<main className='e2e-config-page pa4-l bg-snow mw7 center pa4'>
145-
<Collapsible collapsedLabel="View config" expandedLabel='Hide config' collapsed={isLoadedInIframe}>
148+
{isConfigPage(window.location.hash) ? <Header /> : null}
149+
<section className='e2e-config-page pa4-l bg-snow mw7 center pa4'>
150+
<h1 className='pa0 f3 ma0 mb4 teal tc'>Configure your IPFS Gateway</h1>
146151
<InputSection label='Direct Retrieval'>
147152
<InputToggle
148153
className="e2e-config-page-input"
@@ -224,8 +229,7 @@ function ConfigPage (): React.JSX.Element | null {
224229
<ServiceWorkerReadyButton className="e2e-config-page-button white w-100 pa3" id="save-config" label={isSaving ? 'Saving...' : 'Save Config'} waitingLabel='Waiting for service worker registration...' onClick={() => { void saveConfig() }} />
225230
</div>
226231
{error != null && <span style={{ color: 'red' }}>{error.message}</span>}
227-
</Collapsible>
228-
</main>
232+
</section>
229233
</>
230234
)
231235
}

src/pages/helper-ui.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ConfigProvider } from '../context/config-context.jsx'
77
import { ServiceWorkerProvider } from '../context/service-worker-context.jsx'
88
import { LOCAL_STORAGE_KEYS } from '../lib/local-storage.js'
99
import './default-page-styles.css'
10+
import Config from './config.js'
1011

1112
function HelperUi (): React.JSX.Element {
1213
const [requestPath, setRequestPath] = useState(localStorage.getItem(LOCAL_STORAGE_KEYS.forms.requestPath) ?? '')
@@ -21,8 +22,8 @@ function HelperUi (): React.JSX.Element {
2122

2223
return (
2324
<>
24-
<Header showConfigIcon={true} />
25-
<main className='pa2 pa4-l bg-snow mw7 mv5-l center'>
25+
<Header />
26+
<main className='pa2 pa4-l bg-snow mw7 mv5-l center e2e-helper-ui'>
2627
<h1 className='pa0 f3 ma0 mb4 teal tc'>Fetch & Verify IPFS Content in Browser</h1>
2728
<Form
2829
handleSubmit={handleSubmit}
@@ -37,6 +38,7 @@ function HelperUi (): React.JSX.Element {
3738
</main>
3839

3940
<About />
41+
<Config/>
4042
</>
4143
)
4244
}

test-e2e/config-loading.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getConfig, setConfig } from './fixtures/set-sw-config.js'
33
import { waitForServiceWorker } from './fixtures/wait-for-service-worker.js'
44
import type { ConfigDb } from '../src/lib/config-db'
55

6-
test.describe('/#/ipfs-sw-config', () => {
6+
test.describe('ipfs-sw configuration', () => {
77
const testConfig: ConfigDb = {
88
gateways: [process.env.KUBO_GATEWAY as string, 'http://example.com'],
99
routers: [process.env.KUBO_GATEWAY as string, 'http://example.com/routing/v1'],

0 commit comments

Comments
 (0)