Skip to content

Commit

Permalink
Merge pull request #25 from akirk/api-client
Browse files Browse the repository at this point in the history
API Client
  • Loading branch information
psrpinto authored Sep 9, 2024
2 parents fb12df1 + e73be66 commit 59ac810
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 37 deletions.
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"ts-loader": "^9.5.1",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"typescript": "^5.5.4",
"web-ext": "^8.2.0"
"web-ext": "^8.2.0",
"wp-types": "^4.66.1"
},
"dependencies": {
"@wp-playground/client": "^0.9.31",
Expand Down
49 changes: 49 additions & 0 deletions src/api/ApiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-disable camelcase */

import { PlaygroundClient } from '@wp-playground/client';
import { WP_REST_API_Post } from 'wp-types';

export interface Post {
id: number;
title: string;
}

export class ApiClient {
private readonly playgroundClient: PlaygroundClient;
private readonly _siteUrl: string;

constructor( playgroundClient: PlaygroundClient, siteUrl: string ) {
this.playgroundClient = playgroundClient;
this._siteUrl = siteUrl;
}

get siteUrl(): string {
return this._siteUrl;
}

async getPosts(): Promise< Post[] > {
const response = ( await this.get(
'/wp/v2/posts'
) ) as WP_REST_API_Post[];

return response.map( ( post ) => {
return {
id: post.id,
title: post.title.rendered,
};
} );
}

private async get( route: string ): Promise< object > {
const response = await this.playgroundClient.request( {
url: `/index.php?rest_route=${ route }`,
method: 'GET',
} );
if ( response.httpStatusCode !== 200 ) {
throw Error( response.json.message );
}
return response.json;
}
}

/* eslint-enable camelcase */
14 changes: 9 additions & 5 deletions src/ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import {
useNavigate,
useRouteLoaderData,
} from 'react-router-dom';
import { StrictMode, useEffect } from 'react';
import { StrictMode, useEffect, useState } from 'react';
import { NewSession } from '@/ui/start/NewSession';
import { ViewSession } from '@/ui/session/ViewSession';
import { Home } from '@/ui/start/Home';
import { getConfig, setConfig } from '@/storage/config';
import { getSession, listSessions, Session } from '@/storage/session';
import { PlaceholderPreview } from '@/ui/preview/PlaceholderPreview';
import { SessionContext, SessionProvider } from '@/ui/session/SessionProvider';
import { ApiClient } from '@/api/ApiClient';

export const Screens = {
home: () => '/start/home',
Expand Down Expand Up @@ -75,23 +77,25 @@ function App() {
}, [ location ] );

const session = useRouteLoaderData( 'session' ) as Session;
const [ apiClient, setApiClient ] = useState< ApiClient >();
const sectionContext: SessionContext = { session, apiClient };

const preview = ! session ? (
<PlaceholderPreview />
) : (
<Preview sessionId={ session.id } />
<Preview onReady={ setApiClient } />
);

return (
<>
<SessionProvider value={ sectionContext }>
<div className="app">
<Navbar className={ 'app-nav' } />
<div className="app-main">
<Outlet context={ session } />
<Outlet />
</div>
</div>
<div className="preview">{ preview }</div>
</>
</SessionProvider>
);
}

Expand Down
23 changes: 12 additions & 11 deletions src/ui/preview/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import {
StartPlaygroundOptions,
startPlaygroundWeb,
} from '@wp-playground/client';
import { ApiClient } from '@/api/ApiClient';

const playgroundIframeId = 'playground';

export interface PlaygroundInfo {
url: string;
}

export function Playground( props: {
slug: string;
className?: string;
onReady: ( info: PlaygroundInfo ) => void;
onReady: ( apiClient: ApiClient ) => void;
} ) {
const { slug, className, onReady } = props;

Expand All @@ -29,12 +26,16 @@ export function Playground( props: {
}

initPlayground( iframe, slug )
.then( async ( client: PlaygroundClient ) => {
const info = {
url: await client.absoluteUrl,
};
console.log( 'Playground communication established!', info );
onReady( info );
.then( async ( playgroundClient: PlaygroundClient ) => {
const apiClient = new ApiClient(
playgroundClient,
await playgroundClient.absoluteUrl
);
console.log(
'Playground communication established!',
apiClient.siteUrl
);
onReady( apiClient );
} )
.catch( ( error ) => {
throw error;
Expand Down
27 changes: 12 additions & 15 deletions src/ui/preview/Preview.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { useState } from 'react';
import { PreviewTabBar } from '@/ui/preview/PreviewTabBar';
import { Playground, PlaygroundInfo } from '@/ui/preview/Playground';
import { Playground } from '@/ui/preview/Playground';
import { useSessionContext } from '@/ui/session/SessionProvider';
import { ApiClient } from '@/api/ApiClient';

const tabFront = 0;
const tabAdmin = 1;
const defaultTab = tabFront;

export function Preview( props: { sessionId: string } ) {
const { sessionId } = props;
export function Preview( props: {
onReady: ( apiClient: ApiClient ) => void;
} ) {
const { onReady } = props;
const [ currentTab, setCurrentTab ] = useState< number >( defaultTab );
const [ playgroundInfo, setPlaygroundInfo ] = useState< PlaygroundInfo >();
const { session, apiClient } = useSessionContext();

const previewAdminUrl =
playgroundInfo?.url && playgroundInfo.url?.length > 0
? `${ playgroundInfo.url }/wp-admin/`
apiClient?.siteUrl && apiClient.siteUrl?.length > 0
? `${ apiClient.siteUrl }/wp-admin/`
: '';

const isPlaygroundLoading = previewAdminUrl === '';
Expand All @@ -28,17 +32,10 @@ export function Preview( props: { sessionId: string } ) {
/>
);

const previewFront = (
<Playground
slug={ sessionId }
onReady={ ( info ) => {
setPlaygroundInfo( info );
} }
/>
);
const previewFront = <Playground slug={ session.id } onReady={ onReady } />;

const previewAdmin = (
<iframe title={ `${ sessionId }-admin` } src={ previewAdminUrl } />
<iframe title={ `${ session.id }-admin` } src={ previewAdminUrl } />
);

const showTabBar = ! isPlaygroundLoading;
Expand Down
22 changes: 22 additions & 0 deletions src/ui/session/SessionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createContext, useContext } from 'react';
import { Session } from '@/storage/session';
import { ApiClient } from '@/api/ApiClient';

export interface SessionContext {
session: Session;
apiClient?: ApiClient;
}

const sessionContext = createContext< SessionContext >( {
session: {
id: '',
url: '',
title: '',
},
} );

export const SessionProvider = sessionContext.Provider;

export function useSessionContext() {
return useContext( sessionContext );
}
29 changes: 25 additions & 4 deletions src/ui/session/ViewSession.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import { useOutletContext } from 'react-router-dom';
import { Session } from '@/storage/session';
import { useSessionContext } from '@/ui/session/SessionProvider';
import { Post } from '@/api/ApiClient';
import { useEffect, useState } from 'react';

export function ViewSession() {
const session = useOutletContext() as Session;
const { session, apiClient } = useSessionContext();

const [ posts, setPosts ] = useState< Post[] >( [] );
useEffect( () => {
if ( ! apiClient ) {
return;
}
const getPosts = async () => {
setPosts( await apiClient.getPosts() );
};
void getPosts();
}, [ apiClient?.siteUrl ] );

return (
<>
<span>{ `view session: ${ session.id }` }</span>
<div>view session: { session.id }</div>
{ apiClient?.siteUrl ? (
<div>url: { apiClient.siteUrl }</div>
) : null }
<ul>
{ posts.map( ( post ) => {
return <li key={ post.id }>{ post.title }</li>;
} ) }
</ul>
</>
);
}

0 comments on commit 59ac810

Please sign in to comment.