Skip to content

Commit

Permalink
project
Browse files Browse the repository at this point in the history
  • Loading branch information
lienbaoagora committed Sep 19, 2024
0 parents commit df30380
Show file tree
Hide file tree
Showing 30 changed files with 1,950 additions and 0 deletions.
12 changes: 12 additions & 0 deletions examples/web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Agora IoT Callkit - Web SDK Demo</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
7 changes: 7 additions & 0 deletions examples/web/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";
import ReactDOM from "react-dom/client";

import App from "./src/App";
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);

root.render(<App />);
28 changes: 28 additions & 0 deletions examples/web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "iot-callkit-web-example",
"private": true,
"type": "module",
"main": "./main.tsx",
"scripts": {
"start": "vite --host --open",
"start-prod": "NODE_ENV=production vite --host --open",
"build": "NODE_ENV=production vite build",
"preview": "vite preview"
},
"dependencies": {
"iot-callkit-web": "~2.1.2",
"@vitejs/plugin-react": "^4.1.0",
"antd-mobile": "~5.37.0",
"antd-mobile-icons": "~0.3.0",
"react": "~18.2.0",
"react-dom": "~18.2.0",
"react-router-dom": "^6.16.0"
},
"devDependencies": {
"@types/react": "~18.2.0",
"@types/react-dom": "~18.2.0",
"sass": "^1.64.0",
"vite": "^4.5.3",
"sass-loader": "^13.3.2"
}
}
48 changes: 48 additions & 0 deletions examples/web/src/App.global.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
body {
position: relative;
color: black;
height: 100vh;

font-family: sans-serif;
margin: 0;
}

#app {
display: flex;
flex: 1;
overflow: hidden;
max-height: 100%;
}

.app {
height: 100vh;
display: flex;
flex-direction: column;
}

.container {
width: 100%;
}

.body {
flex: 1;
display: flex;
}
.footer {
flex: 0;
border-top: solid 1px var(--adm-color-border);
}

.top {
position: fixed;
top: 0;
width: 100%;
box-sizing: border-box;
left: 0;
z-index: 99;
background: #ffffff;
}
.content {
overflow-y: auto;
padding-top: 45px;
}
84 changes: 84 additions & 0 deletions examples/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Footer } from "antd-mobile";
import { getAgoraIotEngine } from "iot-callkit-web";
import React, { useEffect, useState } from "react";
import { HashRouter, Navigate, Route, Routes } from "react-router-dom";

import "./App.global.scss";
import defaultSettings from "../src/configs/callkit.config";

import { AuthProvider, useAuth } from "./hooks/useAuth";
import { IotEngineProvider } from "./hooks/useIotEngine";
import { useLocalStorage } from "./hooks/useLocalStorage";
import Home from "./pages/Home";
import Login from "./pages/Login";
import PersonalCenter from "./pages/PersonalCenter";
import Register from "./pages/Register";
import StreamManager from "./pages/StreamManager";
import Settings from "./pages/settings";

export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const { user } = useAuth();

if (!user) {
return <Navigate to="/login" />;
}
return children;
};

const App = () => {
useLocalStorage("settings", defaultSettings);

const [version, setVersion] = useState<{
version: string | undefined;
}>({ version: undefined });

useEffect(() => {
const iotInstance = getAgoraIotEngine();
setVersion({ version: iotInstance.getVersion() });
}, []);

return (
<div className="app">
<div className="body">
<HashRouter>
<AuthProvider>
<IotEngineProvider>
<Routes>
<Route
path="/"
Component={() => (
<ProtectedRoute>
<Home />
</ProtectedRoute>
)}
/>
<Route
path="/stream-manager/:peerNodeId"
Component={() => (
<ProtectedRoute>
<StreamManager />
</ProtectedRoute>
)}
/>
<Route
path="/me"
Component={() => (
<ProtectedRoute>
<PersonalCenter />
</ProtectedRoute>
)}
/>
<Route path="/settings" Component={() => <Settings />} />
<Route path="/login" Component={() => <Login />} />
<Route path="/register" Component={() => <Register />} />
</Routes>
</IotEngineProvider>
</AuthProvider>
</HashRouter>
</div>
<Footer content={`Powered by Agora IoT CallKit ${version.version}`} />
</div>
);
};

export default App;
29 changes: 29 additions & 0 deletions examples/web/src/assets/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.App {
text-align: center;
}

.App-header {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
}

.App-link {
color: #61dafb;
}

.wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.playerContainer {
display: flex;
flex-direction: row;
margin-top: 64px;
}
13 changes: 13 additions & 0 deletions examples/web/src/assets/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@import "~antd/dist/antd.css";

body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
Binary file added examples/web/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/web/src/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions examples/web/src/components/LogSink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { List, Popup } from "antd-mobile";
import { useEffect } from "react";

interface LogSinkProps {
isShowLogSink: boolean;
setIsShowLogSink: (isShowLogSink: boolean) => void;
}

export class log {
static logList: Array<string> = [];
static _logSink(
level: "debug" | "log" | "info" | "warn" | "error",
message?: any,
...optionalParams: any[]
) {
console[level](message, ...optionalParams);
const content = `${optionalParams.map(v => (typeof v === "object" ? v : JSON.stringify(v)))}`;
log.logList.splice(0, 0, `[${level}] ${message} ${content}`);
return content;
}

static clear() {
log.logList = [];
}

static log(message?: any, ...optionalParams: any[]): void {
log._logSink("log", message, optionalParams);
}
}

const LogSink = ({ isShowLogSink, setIsShowLogSink }: LogSinkProps) => {
useEffect(() => {
return () => {
log.clear();
};
}, []);

return (
<>
<Popup
className="logSink"
visible={isShowLogSink}
onMaskClick={() => {
setIsShowLogSink(false);
}}
onClose={() => {
setIsShowLogSink(false);
}}
bodyStyle={{ height: "40vh" }}
>
<List header="logs">
{log.logList.map((log, index) => (
<List.Item key={index}>{log}</List.Item>
))}
</List>
</Popup>
</>
);
};

export default LogSink;
6 changes: 6 additions & 0 deletions examples/web/src/configs/callkit.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
appId: "5ea8ad97b4684c798966b99a965beb9a",
authKey: "59a44ef2b37745fe93c6c660f0700184",
secretKey: "65825d8c98b5461291f91726ef9cfb85",
region: ["cn"],
};
82 changes: 82 additions & 0 deletions examples/web/src/configs/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
export const BASE_URL_HEAD = "https://api.sd-rtn.com/";
export const BASE_URL_TAIL = "/iot/link";
export const CREATE_ACCOUNT = "/open-api/v2/iot-core/secret-node/user/create";
export const ACTIVE_ACCOUNT = "/open-api/v2/iot-core/secret-node/user/activate";
export const HTTP_REQ_CONNECT = "/open-api/v2/connect/create";
const isProd = process.env.NODE_ENV === "production";
export enum Region {
CN = "cn",
NA = "na",
AP = "ap",
EU = "eu",
}

export class Response {
code?: number;
msg?: string;
timestamp?: number;
traceId?: string;
success?: boolean;
data?: any;
constructor(
props?: Partial<{
code?: number;
msg?: string;
timestamp?: number;
traceId?: string;
success?: string;
data?: any;
}>,
) {
Object.assign(this, props);
}
}

function base64Encode(str: string) {
const encoder = new TextEncoder();
const data = encoder.encode(str);
let binaryString = "";
const len = data.byteLength;
for (let i = 0; i < len; i++) {
binaryString += String.fromCharCode(data[i]);
}
return btoa(binaryString);
}

export function generateBasicAuth(key: string, secret: string) {
return base64Encode(key + ":" + secret);
}

export function fetchAPI(req: any): Promise<Response> {
return new Promise((resolve, reject) => {
const body = req.body;
const options = {
method: req.method || "post",
timeout: 30000,
headers: {
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify(body),
};

options.headers = { ...options.headers, ...req.headers };

if (req.body) {
const merged = { ...body, ...req.body };
options.body = JSON.stringify(merged);
}

if (isProd) {
req.url = BASE_URL_HEAD + req.url;
}

fetch(req.url, options)
.then(response => response.json())
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
});
});
}
Loading

0 comments on commit df30380

Please sign in to comment.