Skip to content

Commit

Permalink
feat: add p2p retrieval option (#391)
Browse files Browse the repository at this point in the history
* feat: add config toggle for p2p retrieval

* deps: add helia and bump verified fetch

* feat: load p2p helia

* chore: remove console.log

* feat: try to make recursive gateways optional

* fixup! feat: add config toggle for p2p retrieval

* chore: aegir lint --fix

* chore: install missing deps

* feat: use esbuild for building

* feat: remove webpack

* test: fix e2e tests

* chore: remove timeout only required on my network

* chore: remove copyfiles

* chore: suggestions from self code review

* fix: gateways null when loading sw

* fix: use code-splitting

* fix: firefox doesn't like ESM service workers

* fix: remove type in sw registration

* feat: add git version into index.html

* Revert "feat: try to make recursive gateways optional"

This reverts commit eba97a4.

* fix: bug returning an array with 1 el

* ui: improve contrast for disabled toggle

* feat: add granular config options

* test: fix config layout test

* deps: add missing deps

* fix: unused deps

* fix: make toggles smaller

* fix: avoid setting defaults in inputs

* feat: allow a single router for now

* chore: rename to get verified fetch

* feat: reorder config

* feat: add additional title

* fix: break config UI into sections

* chore: output localhost as listening host

* fix: allow multiple routers

see #402

* fix: run validation onblur to allow editing

* fix: log config as string

otherwise it's not viewable in the console

* feat: add ipip-484 filtering to delegated router

* chore: more left padding on input section

Co-authored-by: Daniel Norman <1992255+2color@users.noreply.github.com>

---------

Co-authored-by: Daniel N <2color@users.noreply.github.com>
Co-authored-by: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 24, 2024
1 parent cb8c662 commit 0db6d94
Show file tree
Hide file tree
Showing 16 changed files with 16,369 additions and 9,525 deletions.
4 changes: 2 additions & 2 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@ if (watchRequested) {
}

if (serveRequested) {
const { host, port } = await ctx.serve({
const { port } = await ctx.serve({
servedir: 'dist',
port: 8345,
host: 'localhost'
})
console.info(`Listening on http://${host}:${port}`)
console.info(`Listening on http://localhost:${port}`)
}
25,319 changes: 15,968 additions & 9,351 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 18 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,27 @@
}
},
"dependencies": {
"@helia/verified-fetch": "^1.4.1",
"@libp2p/logger": "^4.0.10",
"@chainsafe/libp2p-noise": "^16.0.0",
"@chainsafe/libp2p-yamux": "^7.0.1",
"@helia/block-brokers": "^4.0.0",
"@helia/delegated-routing-v1-http-api-client": "^4.1.0",
"@helia/http": "^2.0.0",
"@helia/interface": "^5.0.0",
"@helia/routers": "^2.1.0",
"@helia/verified-fetch": "^2.0.0",
"@libp2p/crypto": "^5.0.5",
"@libp2p/dcutr": "^2.0.8",
"@libp2p/identify": "^3.0.8",
"@libp2p/keychain": "^5.0.7",
"@libp2p/logger": "^5.1.1",
"@libp2p/ping": "^2.0.8",
"@libp2p/websockets": "^9.0.8",
"@libp2p/webtransport": "^5.0.13",
"@multiformats/dns": "^1.0.6",
"@sgtpooki/file-type": "^1.0.1",
"helia": "^5.0.1",
"ipfs-css": "^1.4.0",
"libp2p": "^2.1.9",
"multiformats": "^13.1.0",
"react": "^18.3.0",
"react-dom": "^18.3.1",
Expand Down
9 changes: 9 additions & 0 deletions src/components/input-description.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

export const InputDescription: React.FC<{ description?: string }> = ({ description }) => {
if (description == null || description.length === 0) {
return null
}

return (<span className="charcoal f6 fw1 db pt1 lh-copy mb2">{description}</span>)
}
5 changes: 5 additions & 0 deletions src/components/input-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react'

export const InputLabel: React.FC<{ label: string }> = ({ label }) => {
return (<span className='f5 ma0 pt3 teal fw4 db'>{label}</span>)
}
10 changes: 10 additions & 0 deletions src/components/input-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'

export const InputSection: React.FC<{ label: string, children: React.ReactNode[] }> = ({ label, children }) => {
return (
<div className="bl bw2 br2 b--teal-muted pl3 mb3">
<span className='f3 ma0 teal fw4 db'>{label}</span>
{children}
</div>
)
}
27 changes: 18 additions & 9 deletions src/components/local-storage-input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { useEffect, useState } from 'react'
import React, { useCallback, useEffect, useState } from 'react'
import { InputDescription } from './input-description'
import { InputLabel } from './input-label'

export interface LocalStorageInputProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
localStorageKey: string
Expand Down Expand Up @@ -45,35 +47,42 @@ export default ({ resetKey, localStorageKey, label, placeholder, validationFn, d
validationFn = defaultValidationFunction
}

useEffect(() => {
const updateValue = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(e.target.value)
}, [])

const saveValue = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
const newValue = e.target.value
try {
const err = validationFn?.(value)
const err = validationFn?.(newValue)
if (err != null) {
throw err
}
localStorage.setItem(localStorageKey, preSaveFormat?.(value) ?? value)
setValue(newValue)
localStorage.setItem(localStorageKey, preSaveFormat?.(newValue) ?? newValue)
setError(null)
} catch (err) {
setError(err as Error)
}
}, [value])
}, [validationFn, localStorageKey, preSaveFormat])

props = {
...props,
className: `${props.className ?? ''} flex-column items-start mb3`
className: `${props.className ?? ''} flex-column items-start`
}

return (
<div {...props}>
<label htmlFor={localStorageKey} className='f5 ma0 pt3 teal fw4 db'>{label}</label>
<span className="charcoal-muted f6 fw1 db pt1 lh-copy">{description}</span>
<InputLabel label={label} />
<InputDescription description={description} />
<textarea
className='input-reset ba br2 b--light-silver code lh-copy black-80 bg-white pa2 w-100 mt2'
id={localStorageKey}
name={localStorageKey}
placeholder={placeholder}
value={value}
onChange={(e) => { setValue(e.target.value) }}
onChange={updateValue}
onBlur={saveValue}
/>
{error != null && <span className='db lh-copy red pt1 tr f6 w-100'>{error.message}</span>}
</div>
Expand Down
73 changes: 16 additions & 57 deletions src/components/local-storage-toggle.css
Original file line number Diff line number Diff line change
@@ -1,64 +1,23 @@
/**
Inspiration from https://dev.to/codebubb/create-a-simple-on-off-slide-toggle-with-css-db8
*/

.local-storage-toggle input.status {
display: none;
}
/* .local-storage-toggle input.status + label {
height: 100%;
width: 100%;
} */
.local-storage-toggle input.status + label > .status-switch {
cursor: pointer;
/* width: 100%; */
/* height: 100%; */
position: relative;
background-color: #b7bbc8;
color: white;
transition: all 0.5s ease;
padding: 3px;
border-radius: 3px;
}
.local-storage-toggle input.status + label > .status-switch:before, .local-storage-toggle input.status + label > .status-switch:after {
border-radius: 2px;
height: calc(100% - 6px);
width: calc(50% - 3px);
display: flex;
align-items: center;
position: absolute;
justify-content: center;
transition: all 0.3s ease;
}
.local-storage-toggle input.status + label > .status-switch:before {
background-color: white;
color: black;
box-shadow: 0 0 4px 4px rgba(0, 0, 0, 0.2);
left: 3px;
z-index: 10;
content: attr(data-unchecked);
.transition-all {
transition-property: all;
}
.local-storage-toggle input.status + label > .status-switch:after {
right: 0;
content: attr(data-checked);
/* add strikethrough to show to the user that it's disabled */
text-decoration: line-through;

.transition-transform {
transition-property: transform;
}
.local-storage-toggle input.status:checked + label > .status-switch {
background-color: #40c253;

.duration-200 {
transition-duration: 200ms;
}
.local-storage-toggle input.status:checked + label > .status-switch:after {
left: 0;
content: attr(data-unchecked);
/* add strikethrough to show to the user that it's disabled */
text-decoration: line-through;

.ease-in-out {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.local-storage-toggle input.status:checked + label > .status-switch:before {
color: #40c253;
left: 50%;
content: attr(data-checked);

.translate-x-0 {
transform: translateX(0);
}

.h3-custom {
height: 3rem;
.translate-x-100 {
transform: translateX(100%);
}
60 changes: 49 additions & 11 deletions src/components/local-storage-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,33 @@
*/
import React, { useEffect, useState } from 'react'
import './local-storage-toggle.css'
import { InputDescription } from './input-description'
import { InputLabel } from './input-label'

interface LocalStorageToggleProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
interface LocalStorageToggleProps {
label: string
defaultValue: boolean
description?: string
localStorageKey: string
offLabel: string
onLabel: string
className?: string
onClick?: React.MouseEventHandler<HTMLDivElement>
resetKey: number
}

export const LocalStorageToggle: React.FC<LocalStorageToggleProps> = ({ resetKey, localStorageKey, onLabel = 'Off', offLabel = 'On', ...props }) => {
export const LocalStorageToggle: React.FC<LocalStorageToggleProps> = ({
label,
description = '',
defaultValue,
resetKey,
localStorageKey,
...props
}) => {
const [isChecked, setIsChecked] = useState(() => {
const savedValue = localStorage.getItem(localStorageKey)
return savedValue === 'true'
return getLocalStorageValue(localStorageKey, defaultValue)
})

useEffect(() => {
setIsChecked(localStorage.getItem(localStorageKey) === 'true')
setIsChecked(getLocalStorageValue(localStorageKey, defaultValue))
}, [resetKey])

const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
Expand All @@ -28,11 +39,38 @@ export const LocalStorageToggle: React.FC<LocalStorageToggleProps> = ({ resetKey
}

return (
<div {...props} className={`${props.className} local-storage-toggle input-reset bn black-80 w-100 mb3`}>
<input className="status" style={{ display: 'none' }} id={localStorageKey} type="checkbox" name="status" checked={isChecked} onChange={handleChange} />
<label htmlFor={localStorageKey} className="w-100 h-100">
<div className="status-switch relative h3-custom pointer white bg-gray w-100" data-unchecked={offLabel} data-checked={onLabel} />
<div {...props} className={`${props.className}`}>
<InputLabel label={label} />
<InputDescription description={description} />

<input
type="checkbox"
id={localStorageKey}
checked={isChecked}
onChange={handleChange}
className="dn"
/>
<label
htmlFor={localStorageKey}
className={`relative dib h1 w2 flex-shrink-0 pointer br4 ${
isChecked ? 'bg-green' : 'bg-dark-gray'
} transition-all duration-200 ease-in-out`}
>
<span
className={`absolute top-0 left-0 dib h1 w1 br-100 bg-white shadow-1 ${
isChecked ? 'translate-x-100' : 'translate-x-0'
} transition-transform duration-200 ease-in-out`}
/>
</label>
</div>
)
}

function getLocalStorageValue (localStorageKey: string, defaultValue: boolean): boolean {
const savedValue = localStorage.getItem(localStorageKey)
if (savedValue == null) {
return defaultValue
}

return savedValue === 'true'
}
Loading

0 comments on commit 0db6d94

Please sign in to comment.