Building a Debate App: Part 6

By akohad Apr26,2023

[ad_1]

Decentralization / Social media

The presentations page

git clone https://github.com/jeremyorme/debate.git
cd debate
git checkout release/0.0.4
  • Only one presentation per user per debate — a user adds a presentation to summarize their side of the debate so it doesn’t make sense to have more than one. If a second presentation is added, it overwrites the first.
  • A presentation must specify a URL — that points to the presentation video or document, otherwise it would just be a message.
  • Presentations page provides voting buttons for and against — there is no presumption about which side the user intends to vote for on the presentations page as it displays presentations from both sides.

Let’s begin with the data

export interface IPresentation extends IDbEntry {
title: string;
url: string;
}
    // Presentations

private _presentations: CollectionManager<IPresentation> = new CollectionManager<IPresentation>();

    async loadPresentations(debateId: string) {
if (!this._db)
return;

const collectionName = 'debate-' + debateId + '-presentations';
this._presentations.init(await this._db.collection(collectionName, {
publicAccess: AccessRights.ReadAnyWriteOwn,
conflictResolution: ConflictResolution.LastWriteWins
}));
}

    presentations(): IPresentation[] {
return this._presentations.entries() || [];
}

onPresentations(callback: () => void) {
return this._presentations.onUpdated(callback);
}

addPresentation(presentation: IPresentation) {
if (this._publicKey)
this._presentations.addEntry({ ...presentation, _id: this._publicKey });
}

The presentations page

// ...
import "./PresentationsPage.css";

// ...

interface ContainerParams {
id: string;
}

const PAGE_ID = 'presentations-page';

const PresentationsPage: React.FC<ContainerProps> = ({ appData }) => {

// ...

const [presentations, setPresentations] = useState(appData.presentations());

// ...

useEffect(() => {
appData.loadPresentations(id);
// ...
return appData.onDebatesUpdated(() => {
// ...
appData.loadPresentations(id);
// ...
});
}, []);

useEffect(() => {
return appData.onPresentations(() => {
setPresentations(appData.presentations());
});
}, []);

// ...

const addPresentation = () => {
const presentation: IPresentation = {
...dbEntryDefaults,
// ...
};
appData.addPresentation(presentation);
// ...
}

// ...

return (
<IonPage>
...
<IonTitle>{debateTitle}</IonTitle>
...
<IonContent>
{presentations.filter(p => p.url).map(p => <MessageCard key={p._id} username={p._identity.publicKey.slice(-8)} title={p.title} description="" url={p.url} />)}
</IonContent>
</IonPage>
);
};

export default PresentationsPage;

                    <Route path="/debate/:id/presentations">
<PresentationsPage appData={appData} />
</Route>
                    <IonItem>
<Link to={'/debate/' + id + '/presentations'}>
<IonIcon size="small" icon={videocamSharp} />
</Link>
<IonBadge className="count">11</IonBadge>
</IonItem>

Adding a presentation

                <IonCard>
<IonGrid>
<IonRow>
<IonCol>
<IonInput placeholder="Title" value={title} onIonChange={e => updateTitle(e.detail.value)} />
</IonCol>
</IonRow>
<IonRow>
<IonCol>
<IonInput placeholder="URL" value={url} onIonChange={e => updateUrl(e.detail.value)} />
</IonCol>
<IonCol size="auto">
<IonButton size="small" fill="clear" disabled={url.length == 0} onClick={() => addPresentation()}>
<IonIcon icon={addSharp} />
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</IonCard>
    const [title, setTitle] = useState('');
const [url, setUrl] = useState('');
    const updateTitle = (value: string | null | undefined) => {
if (!value && value != '')
return;

setTitle(value);
};

const updateUrl = (value: string | null | undefined) => {
if (!value && value != '')
return;

setUrl(value);
};

    const addPresentation = () => {
const presentation: IPresentation = {
...dbEntryDefaults,
title,
url
};
appData.addPresentation(presentation);
setTitle('');
setUrl('');
}

Voting buttons

                    <IonButtons slot="end">
<IonButton slot="icon-only" onClick={() => updateOwnVoteDirection(VoteDirection.For)}>
<IonIcon icon={ownVoteDirection == VoteDirection.For ? thumbsUpSharp : thumbsUpOutline} />
</IonButton>
<IonButton slot="icon-only" onClick={() => updateOwnVoteDirection(VoteDirection.Against)}>
<IonIcon icon={ownVoteDirection == VoteDirection.Against ? thumbsDownSharp : thumbsDownOutline} />
</IonButton>
</IonButtons>
git clone https://github.com/jeremyorme/debate.git
cd debate
git checkout release/0.0.5

[ad_2]

Source link

By akohad

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *