feat: add episode channels

This commit is contained in:
jinhojang6 2023-08-16 22:30:17 +09:00
parent af8b026b6e
commit 5a0d79462e
11 changed files with 442 additions and 281 deletions

View File

@ -0,0 +1,67 @@
import { Typography } from '@acid-info/lsd-react'
import styled from '@emotion/styled'
import { LPE } from '../../../types/lpe.types'
import { ApplePodcastsIcon } from '@/components/Icons/ApplePodcastsIcon'
import { GooglePodcastsIcon } from '@/components/Icons/GooglePodcastsIcon'
import { SpotifyIcon } from '@/components/Icons/SpotifyIcon'
import Link from 'next/link'
export type EpisodeChannelProps = {
channels: LPE.Podcast.Channel[]
}
const renderChannel = (channel: LPE.Podcast.Channel) => {
switch (channel.name) {
case LPE.Podcast.ChannelNames.Spotify:
return (
<Channel href={channel.url} target="_blank">
<SpotifyIcon width={16} height={16} />
<Typography variant="body2">Spotify</Typography>
</Channel>
)
case LPE.Podcast.ChannelNames.ApplePodcasts:
return (
<Channel href={channel.url} target="_blank">
<ApplePodcastsIcon width={16} height={16} />
<Typography variant="body2">Apple Podcasts</Typography>
</Channel>
)
case LPE.Podcast.ChannelNames.GooglePodcasts:
return (
<Channel href={channel.url} target="_blank">
<GooglePodcastsIcon width={16} height={16} />
<Typography variant="body2">Google Podcasts</Typography>
</Channel>
)
default:
return null
}
}
const EpisodeChannels = ({ channels }: EpisodeChannelProps) => {
return (
<EpisodeChannelContainer>
{channels.map((channel, idx) => renderChannel(channel))}
</EpisodeChannelContainer>
)
}
const EpisodeChannelContainer = styled.header`
display: flex;
gap: 24px;
align-items: center;
margin-top: 32px;
@media (max-width: 768px) {
padding-top: 32px;
}
`
const Channel = styled(Link)`
display: flex;
align-items: center;
gap: 8px;
text-decoration: none;
`
export default EpisodeChannels

View File

@ -7,6 +7,7 @@ import { default as Stats } from '@/components/Article/Article.Stats'
import { LogosCircleIcon } from '@/components/Icons/LogosCircleIcon' import { LogosCircleIcon } from '@/components/Icons/LogosCircleIcon'
import { useHookstate } from '@hookstate/core' import { useHookstate } from '@hookstate/core'
import { playerState } from '@/components/GlobalAudioPlayer/globalAudioPlayer.state' import { playerState } from '@/components/GlobalAudioPlayer/globalAudioPlayer.state'
import EpisodeChannels from './Episode.Channels'
export type EpisodeHeaderProps = LPE.Podcast.Document & { export type EpisodeHeaderProps = LPE.Podcast.Document & {
url: string url: string
@ -18,6 +19,7 @@ const EpisodeHeader = ({
description, description,
publishedAt, publishedAt,
tags, tags,
channels,
url, url,
readingTime, readingTime,
}: EpisodeHeaderProps) => { }: EpisodeHeaderProps) => {
@ -55,6 +57,7 @@ const EpisodeHeader = ({
Network State Podcast Network State Podcast
</PodcastName> </PodcastName>
{tags && <Tags tags={tags} />} {tags && <Tags tags={tags} />}
{channels && <EpisodeChannels channels={channels} />}
{description && ( {description && (
<EpisodeSubtitle <EpisodeSubtitle
variant="h6" variant="h6"

View File

@ -11,9 +11,7 @@ import { getAudioSourceFromEpisode } from '@/utils/data.utils'
import Image from 'next/image' import Image from 'next/image'
import { playerState } from './globalAudioPlayer.state' import { playerState } from './globalAudioPlayer.state'
import { useHookstate } from '@hookstate/core' import { useHookstate } from '@hookstate/core'
import { episodeState } from './episode.state'
// Hasing it out episodes: https://api.simplecast.com/podcasts/b54c0885-7c72-415d-b032-7d294b78d785/episodes?preview=true
const TEMP_EPISODE_ID = '30d4e2f5-4434-419c-8fc1-a76e4b367e20'
type EpisodeProps = { type EpisodeProps = {
title: string title: string
@ -24,8 +22,8 @@ type EpisodeProps = {
export default function GlobalAudioPlayer() { export default function GlobalAudioPlayer() {
const state = useHookstate(playerState) const state = useHookstate(playerState)
const epState = useHookstate(episodeState)
const episodeId = ''
const ref = useRef<ReactPlayer>(null) const ref = useRef<ReactPlayer>(null)
const [episode, setEpisode] = useState<EpisodeProps>({ const [episode, setEpisode] = useState<EpisodeProps>({
title: '', title: '',
@ -36,7 +34,7 @@ export default function GlobalAudioPlayer() {
useMemo(() => { useMemo(() => {
const getAudioSource = async () => { const getAudioSource = async () => {
const response = await getAudioSourceFromEpisode(TEMP_EPISODE_ID) const response = await getAudioSourceFromEpisode(epState.value.episodeId)
setEpisode({ setEpisode({
title: response.title, title: response.title,
@ -47,7 +45,7 @@ export default function GlobalAudioPlayer() {
} }
getAudioSource() getAudioSource()
}, [episodeId]) }, [epState])
const [showVolume, setShowVolume] = useState(false) const [showVolume, setShowVolume] = useState(false)

View File

@ -0,0 +1,17 @@
import { hookstate } from '@hookstate/core'
// Hasing it out episodes: https://api.simplecast.com/podcasts/b54c0885-7c72-415d-b032-7d294b78d785/episodes?preview=true
const TEMP_EPISODE_ID = '30d4e2f5-4434-419c-8fc1-a76e4b367e20'
export type EpisodeState = {
episodeId: string
}
export const defaultEpisodeState: EpisodeState = {
episodeId: TEMP_EPISODE_ID,
}
export const episodeState =
typeof window === 'undefined'
? hookstate(defaultEpisodeState)
: hookstate<EpisodeState>(defaultEpisodeState)

View File

@ -0,0 +1,27 @@
import { LsdIcon } from '@acid-info/lsd-react'
export const ApplePodcastsIcon = LsdIcon(
(props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
viewBox="0 0 16 16"
{...props}
>
<g clipPath="url(#clip0_541_16016)">
<path
fill="#000"
d="M3.56 0A3.552 3.552 0 000 3.56v8.88A3.552 3.552 0 003.56 16h8.88A3.552 3.552 0 0016 12.44V3.56A3.552 3.552 0 0012.44 0H3.56zm4.35 1.712a5.48 5.48 0 014.037 1.725c.816.848 1.275 1.746 1.51 2.928.08.393.08 1.466.004 1.909a5.67 5.67 0 01-2.16 3.53c-.405.307-1.397.841-1.557.841-.059 0-.064-.06-.037-.306.048-.395.096-.477.32-.571.357-.15.965-.583 1.338-.957a5.096 5.096 0 001.339-2.357c.139-.55.123-1.77-.032-2.336-.485-1.797-1.952-3.195-3.75-3.568-.522-.107-1.471-.107-2 0-1.818.373-3.322 1.84-3.78 3.685-.123.502-.123 1.723 0 2.224.303 1.222 1.093 2.342 2.127 3.008.203.134.448.272.55.315.224.096.272.176.314.57.027.24.02.31-.037.31-.037 0-.31-.117-.597-.256l-.027-.02c-1.648-.81-2.704-2.183-3.088-4.008-.096-.47-.112-1.595-.02-2.027.24-1.16.699-2.066 1.461-2.869 1.099-1.158 2.512-1.77 4.086-1.77H7.91zM8 3.585c.272.003.535.027.737.071 1.856.413 3.173 2.272 2.917 4.116a3.76 3.76 0 01-.81 1.92c-.225.287-.769.767-.865.767-.015 0-.032-.182-.032-.402v-.404l.278-.33c1.045-1.252.97-3.002-.171-4.15-.443-.446-.955-.709-1.616-.83-.427-.079-.517-.079-.965-.006-.68.112-1.207.375-1.675.838-1.147 1.136-1.221 2.894-.176 4.148l.275.33v.406c0 .224-.018.405-.04.405-.02 0-.176-.107-.341-.24l-.023-.007c-.554-.443-1.045-1.228-1.248-1.998-.122-.466-.122-1.35.006-1.814.336-1.252 1.258-2.223 2.538-2.679.274-.097.756-.147 1.21-.14zM7.912 5.58c.206 0 .413.04.562.118.332.18.58.48.694.84.309 1.052-.806 1.973-1.814 1.502h-.01c-.474-.22-.73-.637-.736-1.18 0-.488.272-.914.742-1.163a1.26 1.26 0 01.562-.117zM7.905 8.73c.659-.003 1.138.232 1.314.646.132.31.082 1.288-.146 2.868-.154 1.104-.24 1.383-.453 1.571-.293.26-.71.332-1.104.192h-.002c-.477-.171-.58-.403-.776-1.763-.227-1.58-.277-2.558-.145-2.868.174-.41.649-.644 1.313-.646z"
></path>
</g>
<defs>
<clipPath id="clip0_541_16016">
<path fill="#fff" d="M0 0H16V16H0z"></path>
</clipPath>
</defs>
</svg>
),
{ filled: true },
)

View File

@ -0,0 +1 @@
export * from './ApplePodcastsIcon'

View File

@ -0,0 +1,27 @@
import { LsdIcon } from '@acid-info/lsd-react'
export const GooglePodcastsIcon = LsdIcon(
(props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
viewBox="0 0 16 16"
{...props}
>
<g clipPath="url(#clip0_541_16028)">
<path
fill="#000"
d="M1.001 6.452c-.553 0-1 .447-1 1v1.087a1 1 0 002 0V7.452c0-.553-.446-1-1-1zm13.996 0c-.553 0-1 .447-1 1v1.087a1 1 0 002 0V7.452c0-.553-.446-1-1-1zM4.453 9.725c-.554 0-1 .446-1 1v1.086a1 1 0 102 0v-1.08c0-.553-.447-1-1-1v-.006zm0-6.545c-.554 0-1 .447-1 1v3.571a1 1 0 102 0V4.172c0-.553-.447-1-1-1v.008zm7.092 0c-.554 0-1 .447-1 1v1.093a1 1 0 002 0V4.18c0-.553-.447-1-1-1zM7.999 0c-.553 0-1 .447-1 1v1.087a1 1 0 002 0V1c0-.553-.446-1-1-1zm0 12.903c-.553 0-1 .447-1 1v1.094a1 1 0 002 .006V13.91c0-.547-.446-1-1-1v-.007zm3.546-5.638c-.553 0-1 .454-1 1v3.552a1 1 0 102 0V8.265c0-.554-.446-1-1-1zM8 4.085c-.553 0-1 .454-1 1v5.819a1 1 0 102 0V5.092c0-.553-.446-1-1-1v-.007z"
></path>
</g>
<defs>
<clipPath id="clip0_541_16028">
<path fill="#fff" d="M0 0H16V16H0z"></path>
</clipPath>
</defs>
</svg>
),
{ filled: true },
)

View File

@ -0,0 +1 @@
export * from './GooglePodcastsIcon'

View File

@ -0,0 +1,27 @@
import { LsdIcon } from '@acid-info/lsd-react'
export const SpotifyIcon = LsdIcon(
(props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
viewBox="0 0 16 16"
{...props}
>
<g clipPath="url(#clip0_541_16022)">
<path
fill="#000"
d="M8 0a8 8 0 100 16A8 8 0 008 0zm3.669 11.538a.498.498 0 01-.686.166c-1.879-1.148-4.243-1.408-7.028-.771a.499.499 0 01-.222-.973c3.048-.696 5.662-.396 7.77.892.235.145.31.451.166.686zm.979-2.178a.624.624 0 01-.858.206C9.64 8.244 6.362 7.86 3.818 8.633a.625.625 0 01-.362-1.193c2.905-.882 6.517-.455 8.987 1.063.293.18.385.564.205.857zm.084-2.268C10.154 5.56 5.9 5.419 3.438 6.167a.748.748 0 11-.434-1.432c2.825-.858 7.523-.692 10.492 1.07a.747.747 0 11-.764 1.287z"
></path>
</g>
<defs>
<clipPath id="clip0_541_16022">
<path fill="#fff" d="M0 0H16V16H0z"></path>
</clipPath>
</defs>
</svg>
),
{ filled: true },
)

View File

@ -0,0 +1 @@
export * from './SpotifyIcon'

View File

@ -1,277 +1,269 @@
{ {
"data": { "data": {
"id": "b415119a-6550-5577-b850-eaa61684edeb", "id": "b415119a-6550-5577-b850-eaa61684edeb",
"slug": "title-that-will-become-slug", "slug": "title-that-will-become-slug",
"title": "Title of the Episode; a nice and eye catching title", "title": "Title of the Episode; a nice and eye catching title",
"authors": [ "authors": [
{ {
"name": "@testperson", "name": "@testperson",
"emailAddress": "test@domain.com" "emailAddress": "test@domain.com"
} }
], ],
"description": "Here we can have a summary of the podcast episode. Here we can have a summary of the podcast episode. Here we can have a summary of the podcast episode. Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.", "description": "Here we can have a summary of the podcast episode. Here we can have a summary of the podcast episode. Here we can have a summary of the podcast episode. Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.Here we can have a summary of the podcast episode.",
"publishedAt": "2023-07-11T20:30:00.000Z", "publishedAt": "2023-07-11T20:30:00.000Z",
"episodeNumber": 1, "episodeNumber": 1,
"tags": ["Tools", "Cyber Punk", "Docs"], "tags": ["Tools", "Cyber Punk", "Docs"],
"credits": [ "credits": [
{ {
"id": "6bd84ceb-1f22-41f4-a229-306356306da7", "id": "6bd84ceb-1f22-41f4-a229-306356306da7",
"type": "text", "type": "text",
"html": "<p class=\"c1\"><span class=\"c0\">Episode hosts - Annie McEwen and Molly Webster</span></p>", "html": "<p class=\"c1\"><span class=\"c0\">Episode hosts - Annie McEwen and Molly Webster</span></p>",
"text": "Episode hosts - Annie McEwen and Molly Webster", "text": "Episode hosts - Annie McEwen and Molly Webster",
"classNames": [ "classNames": ["c1"],
"c1" "footnotes": [],
], "order": 9,
"footnotes": [], "tagName": "p",
"order": 9, "labels": []
"tagName": "p", },
"labels": [] {
}, "id": "97c48663-da36-4c11-be41-b3a507aa2e21",
{ "type": "text",
"id": "97c48663-da36-4c11-be41-b3a507aa2e21", "html": "<p class=\"c1\"><span class=\"c0\">Produced by - Annie McEwen and Becca Bressler </span></p>",
"type": "text", "text": "Produced by - Annie McEwen and Becca Bressler ",
"html": "<p class=\"c1\"><span class=\"c0\">Produced by - Annie McEwen and Becca Bressler </span></p>", "classNames": ["c1"],
"text": "Produced by - Annie McEwen and Becca Bressler ", "footnotes": [],
"classNames": [ "order": 10,
"c1" "tagName": "p",
], "labels": []
"footnotes": [], },
"order": 10, {
"tagName": "p", "id": "c481e411-165f-4fb0-a5da-e73b05f1b7b7",
"labels": [] "type": "text",
}, "html": "<p class=\"c1\"><span class=\"c0\">With help from - Matt Kielty</span></p>",
{ "text": "With help from - Matt Kielty",
"id": "c481e411-165f-4fb0-a5da-e73b05f1b7b7", "classNames": ["c1"],
"type": "text", "footnotes": [],
"html": "<p class=\"c1\"><span class=\"c0\">With help from - Matt Kielty</span></p>", "order": 11,
"text": "With help from - Matt Kielty", "tagName": "p",
"classNames": [ "labels": []
"c1" },
], {
"footnotes": [], "id": "ef86751f-06d3-4468-a2aa-a97dd378438d",
"order": 11, "type": "text",
"tagName": "p", "html": "<p class=\"c1\"><span class=\"c0\">Original music and sound design contributed by - Jeremy Bloom, Annie McEwen, Matt Kielty</span></p>",
"labels": [] "text": "Original music and sound design contributed by - Jeremy Bloom, Annie McEwen, Matt Kielty",
}, "classNames": ["c1"],
{ "footnotes": [],
"id": "ef86751f-06d3-4468-a2aa-a97dd378438d", "order": 12,
"type": "text", "tagName": "p",
"html": "<p class=\"c1\"><span class=\"c0\">Original music and sound design contributed by - Jeremy Bloom, Annie McEwen, Matt Kielty</span></p>", "labels": []
"text": "Original music and sound design contributed by - Jeremy Bloom, Annie McEwen, Matt Kielty", },
"classNames": [ {
"c1" "id": "d42cfb64-3b8a-4b82-b7db-d80b3346f441",
], "type": "text",
"footnotes": [], "html": "<p class=\"c1\"><span class=\"c0\">Mixing by - Jeremy Bloom</span></p>",
"order": 12, "text": "Mixing by - Jeremy Bloom",
"tagName": "p", "classNames": ["c1"],
"labels": [] "footnotes": [],
}, "order": 13,
{ "tagName": "p",
"id": "d42cfb64-3b8a-4b82-b7db-d80b3346f441", "labels": []
"type": "text", },
"html": "<p class=\"c1\"><span class=\"c0\">Mixing by - Jeremy Bloom</span></p>", {
"text": "Mixing by - Jeremy Bloom", "id": "82fb6107-bde7-43bf-921b-f310d62c9280",
"classNames": [ "type": "text",
"c1" "html": "<p class=\"c1\"><span class=\"c0\">With dialogue mixing by - Arianne Wack </span></p>",
], "text": "With dialogue mixing by - Arianne Wack ",
"footnotes": [], "classNames": ["c1"],
"order": 13, "footnotes": [],
"tagName": "p", "order": 14,
"labels": [] "tagName": "p",
}, "labels": []
{ },
"id": "82fb6107-bde7-43bf-921b-f310d62c9280", {
"type": "text", "id": "bc6bd5f9-a50a-48be-bf2a-fb600a611f99",
"html": "<p class=\"c1\"><span class=\"c0\">With dialogue mixing by - Arianne Wack </span></p>", "type": "text",
"text": "With dialogue mixing by - Arianne Wack ", "html": "<p class=\"c1\"><span class=\"c0\">Fact-checking by - Diane Kelly</span></p>",
"classNames": [ "text": "Fact-checking by - Diane Kelly",
"c1" "classNames": ["c1"],
], "footnotes": [],
"footnotes": [], "order": 15,
"order": 14, "tagName": "p",
"tagName": "p", "labels": []
"labels": [] },
}, {
{ "id": "81b77086-18a6-41a4-8938-888958d53aef",
"id": "bc6bd5f9-a50a-48be-bf2a-fb600a611f99", "type": "text",
"type": "text", "html": "<p class=\"c1\"><span class=\"c0\">And edited by - Alex Neason</span></p>",
"html": "<p class=\"c1\"><span class=\"c0\">Fact-checking by - Diane Kelly</span></p>", "text": "And edited by - Alex Neason",
"text": "Fact-checking by - Diane Kelly", "classNames": ["c1"],
"classNames": [ "footnotes": [],
"c1" "order": 16,
], "tagName": "p",
"footnotes": [], "labels": []
"order": 15, }
"tagName": "p", ],
"labels": [] "transcription": [
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">You ready to get into it?</span></p>"
"id": "81b77086-18a6-41a4-8938-888958d53aef", },
"type": "text", {
"html": "<p class=\"c1\"><span class=\"c0\">And edited by - Alex Neason</span></p>", "html": "<p class=\"c1\"><span class=\"c0\">Everybody. Welcome back. Bringing you another amazing interview, hashing it out, interview, doing it the way we love. I'm here solo dolo today. Well, not so well, though. I'm interviewing someone, but as far as hosts go, I'm so low on this one. Today we're going to talk a little bit about centralized messaging.</span></p>"
"text": "And edited by - Alex Neason", },
"classNames": [ {
"c1" "html": "<p class=\"c1\"><span class=\"c0\">And I'm joined with Franck Royer, and he wanted it now. Hes a Waku guy. So we're going to call him Waku guy. Before we do that, Franck, because you introduce yourself. To the audience.. So I'll try not to just dive straight into Waku, but I feel like that's the only way to do it, right?</span></p>"
], },
"footnotes": [], {
"order": 16, "html": "<p class=\"c1\"><span class=\"c0\">So for those unfamiliar with what Waku is, could you give us like a  quick brief message, like a brief overview of Waku and then we're going to try to peel away the layers and get a little bit deeper. All right. I like that. So it's a if this were to have trouble with an ephemeral communication network.</span></p>"
"tagName": "p", },
"labels": [] {
} "html": "<p class=\"c1\"><span class=\"c0\">Okay. So I do know that there's a lot of projects working on decentralized messaging. But when you say decentralized messaging, I don't think a lot of people quite understand what it is and why it's needed. So I guess we could start there. Like what is the centralized messaging in comparison to what people are used to? And then we'll go to the tail end of that question and so yeah.</span></p>"
], },
"transcription": [ {
{ "html": "<p class=\"c1\"><span class=\"c0\">Mm hmm. So that's the biggest part about it is just removing what we're saying, the centralize or removing the server, its user got it. Many, not many servers, but many different failure points. And then you can't just boot people off, right? If they want a message, they can message. Okay, that's good. Now, I guess moving it to logos, right?</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">You ready to get into it?</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">We've mentioned logo several times before on the podcast and guess what? Audience We're going to continue to mention logos because it's what we do. But Wakue was considered one of the foundational projects or logos was that hmm, yeah. Okay. So why is secure ephemeral messaging like so foundational to these decentralized applications? Right? Like, why is this needed? Like, it's absolutely needed.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Everybody. Welcome back. Bringing you another amazing interview, hashing it out, interview, doing it the way we love. I'm here solo dolo today. Well, not so well, though. I'm interviewing someone, but as far as hosts go, I'm so low on this one. Today we're going to talk a little bit about centralized messaging.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Oh, we can I was going to ask you that would go straight into some use cases. Let's give us some examples.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">And I'm joined with Franck Royer, and he wanted it now. Hes a Waku guy. So we're going to call him Waku guy. Before we do that, Franck, because you introduce yourself. To the audience.. So I'll try not to just dive straight into Waku, but I feel like that's the only way to do it, right?</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">All right. So we're back for round two of the Franck interview. I've been saying your name wrong for what appears to be years now. I mean, I've been saying it right as an American, but from way back for round two, I wanted to get a piece of the interview because for those who don't know, I also am peripherally a part of Waku.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So for those unfamiliar with what Waku is, could you give us like a  quick brief message, like a brief overview of Waku and then we're going to try to peel away the layers and get a little bit deeper. All right. I like that. So it's a if this were to have trouble with an ephemeral communication network.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">And we're actually all are in some way, shape or form. And I have additional context or questions that I'd like to kind of dive into in this. And I think in the first interview, we got a really good foundation as to why Waku exists, what is decentralized messaging, how it fits into the ecosystem and kind of what's wrong with the Internet as it is today.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Okay. So I do know that there's a lot of projects working on decentralized messaging. But when you say decentralized messaging, I don't think a lot of people quite understand what it is and why it's needed. So I guess we could start there. Like what is the centralized messaging in comparison to what people are used to? And then we'll go to the tail end of that question and so yeah.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">But I wanted to dive further into some of the details on how it works and maybe some of the tradeoffs as you build up from like Waku Relay into the different protocols that are available that are built on top of Waku relay. So to start, can you give me like the concept of a gossip network, Like what is a gossip network and how are messages passed around this?</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Mm hmm. So that's the biggest part about it is just removing what we're saying, the centralize or removing the server, its user got it. Many, not many servers, but many different failure points. And then you can't just boot people off, right? If they want a message, they can message. Okay, that's good. Now, I guess moving it to logos, right?</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So we should probably address the cat in the room here. Jesse has decided that he is now an anon person and would be doing all videos with some virtual avatar and a process of doing that. He's also put up a graphic of a gossip network here, which is basically, if I were to repeat that back to you, a well-connected group of nodes that everyone's connected to all people, you connect to a specific number of people.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">We've mentioned logo several times before on the podcast and guess what? Audience We're going to continue to mention logos because it's what we do. But Wakue was considered one of the foundational projects or logos was that hmm, yeah. Okay. So why is secure ephemeral messaging like so foundational to these decentralized applications? Right? Like, why is this needed? Like, it's absolutely needed.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So you have a select number of neighbors for gossip sub that is six people. So every person tries to maintain six connections and then when a message gets passed, it passes to it's it passes that message to all of its six neighbors, so on and so forth, until basically the entire network has been saturated with that message. Right.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Oh, we can I was going to ask you that would go straight into some use cases. Let's give us some examples.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So that allows some redundancy and some sensors like some censorship resistance, some some resiliency in the network. So if one person goes out, the message still gets routed and saturates the network. And I think that was an important distinction that needs to be made here, is that like Wendy was asking a question in the previous episode, I'm not sure if it'll make it into the air.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">All right. So we're back for round two of the Franck interview. I've been saying your name wrong for what appears to be years now. I mean, I've been saying it right as an American, but from way back for round two, I wanted to get a piece of the interview because for those who don't know, I also am peripherally a part of Waku.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">It was, I'm sending a message to someone, right? And that's not necessarily what we're doing with Gossip Sub or Whacko. I'm broadcasting a message and someone knows where to listen. I think that's an important distinction to make and add to that more generally speaking, that the tradeoff you're making here is bandwidth consumption or redundancy and computation, like how much work it takes to propagate a message.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">And we're actually all are in some way, shape or form. And I have additional context or questions that I'd like to kind of dive into in this. And I think in the first interview, we got a really good foundation as to why Waku exists, what is decentralized messaging, how it fits into the ecosystem and kind of what's wrong with the Internet as it is today.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">And I'll fast that message gets propagated. So if you look at it from each extreme right, if you just start with one, each person maintains one connection in the network, right? That means that you have a very inefficient network in terms of how message gets propagated across right? Because if everyone relays a message, then you basically have to wrap that message to every single person with the in number of hops in being the size of the network.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">But I wanted to dive further into some of the details on how it works and maybe some of the tradeoffs as you build up from like Waku Relay into the different protocols that are available that are built on top of Waku relay. So to start, can you give me like the concept of a gossip network, Like what is a gossip network and how are messages passed around this?</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Right. But there's no redundancy. So basically everyone gets that message once. But if we do the opposite of that and everyone is connected to everyone else, that's a fully connected mesh or fully connected network, then everyone receives that message in a number of times. Basically, they just keep just you just redundantly keep receiving it, but you get it really, really fast.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So we should probably address the cat in the room here. Jesse has decided that he is now an anon person and would be doing all videos with some virtual avatar and a process of doing that. He's also put up a graphic of a gossip network here, which is basically, if I were to repeat that back to you, a well-connected group of nodes that everyone's connected to all people, you connect to a specific number of people.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">And so there's a tradeoff somewhere in the middle of like how many how do we maintain the minimum out of connections and message redundancy while maximize what while minimizing the latency, the time it takes to completely saturate the network with that as it's right? And so you're looking for somewhere in the middle so that you get this sense of sender receiver anonymity while also still having some reasonable like latency and bandwidth consumption associated with sending a message.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So you have a select number of neighbors for gossip sub that is six people. So every person tries to maintain six connections and then when a message gets passed, it passes to it's it passes that message to all of its six neighbors, so on and so forth, until basically the entire network has been saturated with that message. Right.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">And so based on those simulations that protocol labs have done, six was a good way. It was a good number. It was the best number they found for Gossip sub, and that's what Waku was built on for gossip. So so now we can assume, you know, we have this, this gossip sub network right. That is what is, what is the difference between the P2P gossip sub and what Waku provides?</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So that allows some redundancy and some sensors like some censorship resistance, some some resiliency in the network. So if one person goes out, the message still gets routed and saturates the network. And I think that was an important distinction that needs to be made here, is that like Wendy was asking a question in the previous episode, I'm not sure if it'll make it into the air.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Why don't people just use the peer to peer gossip So like, why would they why would they want to use Waku at least like, well, we're going to start with just relay, right? Relay is the kind of foundational protocol for how Waku works. What does that add on top of a gossip sub network? Get them getting. Yeah, there's there's a little subtlety there right.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">It was, I'm sending a message to someone, right? And that's not necessarily what we're doing with Gossip Sub or Whacko. I'm broadcasting a message and someone knows where to listen. I think that's an important distinction to make and add to that more generally speaking, that the tradeoff you're making here is bandwidth consumption or redundancy and computation, like how much work it takes to propagate a message.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So like if a if a light client or mobile phone. Right. Can't handle the main network and it wants to try and ask a node for a specific set of messages, there's some level of obfuscating what those messages are right need so they can use bloom Filters are typically the way of doing this, saying I'm I'm looking for messages that look like A, B and C, and the more detailed you are, the more accurate exactly what the more narrowed down the messages you're looking for.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">And I'll fast that message gets propagated. So if you look at it from each extreme right, if you just start with one, each person maintains one connection in the network, right? That means that you have a very inefficient network in terms of how message gets propagated across right? Because if everyone relays a message, then you basically have to wrap that message to every single person with the in number of hops in being the size of the network.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">If you're really broad, you can say, give me all the messages that have the word two in them. Or like, you know, something that allows for the node to answer that while not exposing the details of the message to they can't read them, they're just setting encrypted messages. But like there is some level of privacy loss if you're asking for a group of messages because you just said it gives you the IP and whatever whatever you've asked for, they can make that connection.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Right. But there's no redundancy. So basically everyone gets that message once. But if we do the opposite of that and everyone is connected to everyone else, that's a fully connected mesh or fully connected network, then everyone receives that message in a number of times. Basically, they just keep just you just redundantly keep receiving it, but you get it really, really fast.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So if you're routing as a full node and doing full relay and parsing things on, then you've, you've, you've, you, you're not giving me that information. Whenever you ask for whatever messages you're listening to. And that's a layer of good. Now it's a that's a developer choice. So the people who build the applications kind of choose how these content topics could be used.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">And so there's a tradeoff somewhere in the middle of like how many how do we maintain the minimum out of connections and message redundancy while maximize what while minimizing the latency, the time it takes to completely saturate the network with that as it's right? And so you're looking for somewhere in the middle so that you get this sense of sender receiver anonymity while also still having some reasonable like latency and bandwidth consumption associated with sending a message.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">And eventually we'll have one of the things we're currently working on in doing research and within VAC is kind of automating this sharding or automating the way in which people belong to specific content topic as the network scales out so that you maintain this level of reasonable anonymity or anonymity anonymity while keeping the resources required to do messages low Codex as it stands today and like this is part of ongoing research, is how do we scale walk properly?</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">And so based on those simulations that protocol labs have done, six was a good way. It was a good number. It was the best number they found for Gossip sub, and that's what Waku was built on for gossip. So so now we can assume, you know, we have this, this gossip sub network right. That is what is, what is the difference between the P2P gossip sub and what Waku provides?</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Because if you if you can you can misuse these kind of content topics pretty pretty bad. So if you spam the network with a bunch of pictures, then everyone passes things on, it degrades the quality of the network, right? But like, there's ways of like status now currently uses, sends pictures and so on and prior profile settings and a bunch of other things across a crosswalk which are in some cases larger than one megabyte.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Why don't people just use the peer to peer gossip So like, why would they why would they want to use Waku at least like, well, we're going to start with just relay, right? Relay is the kind of foundational protocol for how Waku works. What does that add on top of a gossip sub network? Get them getting. Yeah, there's there's a little subtlety there right.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So there's a bunch of kind of efficiency tweaks you can do to keep specific media sensible via Waco and, and not like mitigating things whether that you have like this kind of media content shard. So like you just you propagate media through a different part of the network and that's this distinction I think is worth making that developers who are thinking about using Waku should should consider when they're thinking about how to use walk, who is used different.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So like if a if a light client or mobile phone. Right. Can't handle the main network and it wants to try and ask a node for a specific set of messages, there's some level of obfuscating what those messages are right need so they can use bloom Filters are typically the way of doing this, saying I'm I'm looking for messages that look like A, B and C, and the more detailed you are, the more accurate exactly what the more narrowed down the messages you're looking for.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">If you think about a gossip tub topic that's ostensibly a network, that's the entire network. And then if you think about content topics, those are basically contents, right? Those are conversations that are being happened. And so what you're trying to do is strategically use content topics so that you're listening and propagating things you want to do to various people so you can be kind of selective on where you send things and who should be listening to it.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">If you're really broad, you can say, give me all the messages that have the word two in them. Or like, you know, something that allows for the node to answer that while not exposing the details of the message to they can't read them, they're just setting encrypted messages. But like there is some level of privacy loss if you're asking for a group of messages because you just said it gives you the IP and whatever whatever you've asked for, they can make that connection.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">So you're not so not everyone is listening to everything or propagating everything. People are able to kind of pick and choose what they to pay attention to and contribute to when they're when they're contributing to the network. Right? If at some point we can maybe get into like as a if I run a if I run a node, I'm only propagating messages associated with these things because that's what I care about.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So if you're routing as a full node and doing full relay and parsing things on, then you've, you've, you've, you, you're not giving me that information. Whenever you ask for whatever messages you're listening to. And that's a layer of good. Now it's a that's a developer choice. So the people who build the applications kind of choose how these content topics could be used.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">That's what I'm trying to support from the network. And so you have a network of nodes that are just doing the work that they think is important while not being inundated with all of the work of the entire network, which allows kind of this large, amorphous network to scale autonomously.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">And eventually we'll have one of the things we're currently working on in doing research and within VAC is kind of automating this sharding or automating the way in which people belong to specific content topic as the network scales out so that you maintain this level of reasonable anonymity or anonymity anonymity while keeping the resources required to do messages low Codex as it stands today and like this is part of ongoing research, is how do we scale walk properly?</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Jesse Yeah, I think that's perfect. And also like Jesse, that's a good analogy for how status plans to use Waku and it's also highlights this kind of optionality that developers have to leverage different classes of topics and content topics to efficiently serve their their users in the way they want to and hopefully pass on those options to them to do things the way they want to.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Because if you if you can you can misuse these kind of content topics pretty pretty bad. So if you spam the network with a bunch of pictures, then everyone passes things on, it degrades the quality of the network, right? But like, there's ways of like status now currently uses, sends pictures and so on and prior profile settings and a bunch of other things across a crosswalk which are in some cases larger than one megabyte.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Like what you just described was status users getting to choose quite a bit of options, not only and potentially who relays messages and the latency versus privacy aspect of it, but also options for incentivization within their own community as well. So we're like by providing options to developers, they're able to choose a lot of pass those options on to their users to then let them do what they want to do.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So there's a bunch of kind of efficiency tweaks you can do to keep specific media sensible via Waco and, and not like mitigating things whether that you have like this kind of media content shard. So like you just you propagate media through a different part of the network and that's this distinction I think is worth making that developers who are thinking about using Waku should should consider when they're thinking about how to use walk, who is used different.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">And I think that's an important aspect of this. They're not pigeonholing people into a specific set of things. We're passing on a lot of options, though. The last point of this that I think we haven't gotten to. One of the protocols built on top of relay is the store protocol. Can you kind of dive into what that is and why it exists?</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">If you think about a gossip tub topic that's ostensibly a network, that's the entire network. And then if you think about content topics, those are basically contents, right? Those are conversations that are being happened. And so what you're trying to do is strategically use content topics so that you're listening and propagating things you want to do to various people so you can be kind of selective on where you send things and who should be listening to it.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Jesse Just jumping in…</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">So you're not so not everyone is listening to everything or propagating everything. People are able to kind of pick and choose what they to pay attention to and contribute to when they're when they're contributing to the network. Right? If at some point we can maybe get into like as a if I run a if I run a node, I'm only propagating messages associated with these things because that's what I care about.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">This is a reasonable place to wrap, I think. What's the what do you want people to do? Like if people listening to you, how do they learn more? What do you want it to go? How do they contribute it? Let it run a walk through node Like what are they like? How do they figure more out</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">That's what I'm trying to support from the network. And so you have a network of nodes that are just doing the work that they think is important while not being inundated with all of the work of the entire network, which allows kind of this large, amorphous network to scale autonomously.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Thanks, Frank.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Jesse Yeah, I think that's perfect. And also like Jesse, that's a good analogy for how status plans to use Waku and it's also highlights this kind of optionality that developers have to leverage different classes of topics and content topics to efficiently serve their their users in the way they want to and hopefully pass on those options to them to do things the way they want to.</span></p>" },
}, {
{ "html": "<p class=\"c1\"><span class=\"c0\">Frank My bad.</span></p>"
"html": "<p class=\"c1\"><span class=\"c0\">Like what you just described was status users getting to choose quite a bit of options, not only and potentially who relays messages and the latency versus privacy aspect of it, but also options for incentivization within their own community as well. So we're like by providing options to developers, they're able to choose a lot of pass those options on to their users to then let them do what they want to do.</span></p>" }
}, ],
{ "channels": [
"html": "<p class=\"c1\"><span class=\"c0\">And I think that's an important aspect of this. They're not pigeonholing people into a specific set of things. We're passing on a lot of options, though. The last point of this that I think we haven't gotten to. One of the protocols built on top of relay is the store protocol. Can you kind of dive into what that is and why it exists?</span></p>" {
}, "name": "youtube",
{ "url": "https://www.youtube.com/watch?v=vmx_oOb2On0"
"html": "<p class=\"c1\"><span class=\"c0\">Jesse Just jumping in…</span></p>" },
}, {
{ "name": "apple_podcasts",
"html": "<p class=\"c1\"><span class=\"c0\">This is a reasonable place to wrap, I think. What's the what do you want people to do? Like if people listening to you, how do they learn more? What do you want it to go? How do they contribute it? Let it run a walk through node Like what are they like? How do they figure more out</span></p>" "url": "https://podcasts.apple.com/us/podcast/franck-royer-decentralized-messaging/id1376906132?i=1000618673846"
}, },
{ {
"html": "<p class=\"c1\"><span class=\"c0\">Thanks, Frank.</span></p>" "name": "spotify",
}, "url": "https://open.spotify.com/show/3WkYBYaZ4W1Z8gzBlOvr7y"
{ },
"html": "<p class=\"c1\"><span class=\"c0\">Frank My bad.</span></p>" {
} "name": "google_podcasts",
], "url": "https://podcasts.google.com/feed/aHR0cHM6Ly9mZWVkcy5zaW1wbGVjYXN0LmNvbS9xd0d2bGoyag/episode/OGQ5ZmE0NzgtMGUxNy00YWIzLTk1NzgtYTNiYTEyMjMwY2Jm?sa=X&ved=0CAUQkfYCahcKEwiwz7SVoeGAAxUAAAAAHQAAAAAQNQ"
"channels": [ }
{ ],
"name": "youtube", "coverImage": {
"url": "https://www.youtube.com/watch?v=vmx_oOb2On0" "id": "08bd8535-d7b5-459e-85a0-183feb502e08",
}, "type": "image",
{ "alt": "",
"name": "youtube", "url": "https://images.cdn.unbody.io/00f8908f-9dff-456e-9640-13defd9ae433/image/a04e5542-d027-44d5-b914-bd4cadf17d25_image1.png",
"url": "https://www.youtube.com/watch?v=vmx_oOb2On0" "height": 1223,
} "order": 7,
], "width": 1999,
"coverImage": { "labels": []
"id": "08bd8535-d7b5-459e-85a0-183feb502e08",
"type": "image",
"alt": "",
"url": "https://images.cdn.unbody.io/00f8908f-9dff-456e-9640-13defd9ae433/image/a04e5542-d027-44d5-b914-bd4cadf17d25_image1.png",
"height": 1223,
"order": 7,
"width": 1999,
"labels": []
},
"show": {
"id": "426d4e4a-98db-5ba2-a9e6-a9d989a34022",
"slug": "hashing-it-out",
"title": "Hashing It Out",
"numberOfEpisodes": 1,
"hosts": [
{
"name": "Host",
"emailAddress": "host@gmail.com"
}
],
"url": "/podcasts/hashing-it-out",
"description": "",
"logo": {
"alt": "",
"url": "https://images.cdn.unbody.io/00f8908f-9dff-456e-9640-13defd9ae433/image/d4ecc97f-bcef-411d-b31a-639261623b25_image1.png",
"width": 1999,
"height": 1123
},
"episodes": []
},
"featured": false,
"highlighted": false
}, },
"errors": null "show": {
"id": "426d4e4a-98db-5ba2-a9e6-a9d989a34022",
"slug": "hashing-it-out",
"title": "Hashing It Out",
"numberOfEpisodes": 1,
"hosts": [
{
"name": "Host",
"emailAddress": "host@gmail.com"
}
],
"url": "/podcasts/hashing-it-out",
"description": "",
"logo": {
"alt": "",
"url": "https://images.cdn.unbody.io/00f8908f-9dff-456e-9640-13defd9ae433/image/d4ecc97f-bcef-411d-b31a-639261623b25_image1.png",
"width": 1999,
"height": 1123
},
"episodes": []
},
"featured": false,
"highlighted": false
},
"errors": null
} }