generated from IBM/pwa-lit-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add new features and update routes
- Enabled service worker generation in rollup.config.js. - Deleted the "About" page (page-about.ts). - Enhanced page-home.ts with new text input, image upload, and navigation functionalities. - Added support for session storage and routing to the chat page after interactions. - Updated routes.ts to replace the "About" page with "User" and "Chat" pages. - Added new imports and lazy loading for the updated routes. Improved overall structure and modularity of the project.
- Loading branch information
Showing
7 changed files
with
551 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/** | ||
* Network utilities for communicating with the backend server | ||
*/ | ||
|
||
const BASE_URL = 'https://druid.eecs.umich.edu'; | ||
const API_ENDPOINTS = { | ||
auth: `${BASE_URL}/auth`, | ||
nlip: `${BASE_URL}/nlip`, | ||
upload: `${BASE_URL}/upload`, | ||
}; | ||
|
||
interface Message { | ||
format: 'text' | 'binary'; | ||
subformat: string; | ||
content: string; | ||
} | ||
|
||
interface NLIPRequest { | ||
format: 'text'; | ||
subformat: string; | ||
content: string; | ||
submessages?: Message[]; | ||
} | ||
|
||
interface APIResponse { | ||
response: string; | ||
// Add other response fields if needed | ||
} | ||
|
||
/** | ||
* Get authentication URL for a specific provider | ||
*/ | ||
export async function getAuthUrl(): Promise<string> { | ||
try { | ||
const response = await fetch(API_ENDPOINTS.auth); | ||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
const data = await response.json(); | ||
return data.url; | ||
} catch (error) { | ||
console.error('Error getting auth URL:', error); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Send a text message to the NLIP endpoint | ||
*/ | ||
export async function sendTextMessage(text: string): Promise<string> { | ||
const request: NLIPRequest = { | ||
format: 'text', | ||
subformat: 'english', | ||
content: text, | ||
}; | ||
|
||
try { | ||
const response = await fetch(API_ENDPOINTS.nlip, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(request), | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
|
||
const data: APIResponse = await response.json(); | ||
return data.response; | ||
} catch (error) { | ||
console.error('Error sending text message:', error); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Send an image with an optional prompt to the NLIP endpoint | ||
*/ | ||
export async function sendImageMessage( | ||
prompt: string, | ||
base64Image: string, | ||
mimeType: string | ||
): Promise<string> { | ||
// Extract the image format from the MIME type (e.g., 'image/jpeg' -> 'jpeg') | ||
const imageFormat = mimeType.split('/')[1]; | ||
|
||
const request: NLIPRequest = { | ||
format: 'text', | ||
subformat: 'english', | ||
content: prompt || 'Describe this picture', | ||
submessages: [ | ||
{ | ||
format: 'binary', | ||
subformat: imageFormat, | ||
content: base64Image, | ||
}, | ||
], | ||
}; | ||
|
||
try { | ||
const response = await fetch(API_ENDPOINTS.nlip, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(request), | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
|
||
const data: APIResponse = await response.json(); | ||
return data.response; | ||
} catch (error) { | ||
console.error('Error sending image message:', error); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Upload a file using form data | ||
*/ | ||
export async function uploadFile(file: File): Promise<string> { | ||
const formData = new FormData(); | ||
formData.append('file', file); | ||
|
||
try { | ||
const response = await fetch(API_ENDPOINTS.upload, { | ||
method: 'POST', | ||
body: formData, | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
|
||
const data = await response.json(); | ||
return data.url; // Assuming the server returns the URL of the uploaded file | ||
} catch (error) { | ||
console.error('Error uploading file:', error); | ||
throw error; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/** | ||
* Copyright (c) IBM, Corp. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import { html, css } from 'lit'; | ||
import { customElement, property } from 'lit/decorators.js'; | ||
|
||
import { PageElement } from '../helpers/page-element.js'; | ||
|
||
@customElement('page-chat') | ||
export class PageChat extends PageElement { | ||
@property({ type: String }) userPrompt = ''; | ||
@property({ type: String }) aiResponse = ''; | ||
|
||
connectedCallback(): void { | ||
super.connectedCallback?.(); | ||
// Load chat data from sessionStorage | ||
const chatData = sessionStorage.getItem('chatData'); | ||
if (chatData) { | ||
const { userPrompt, aiResponse } = JSON.parse(chatData); | ||
this.userPrompt = userPrompt; | ||
this.aiResponse = aiResponse; | ||
// Clear the data after loading | ||
sessionStorage.removeItem('chatData'); | ||
} | ||
} | ||
|
||
static styles = css` | ||
@supports (padding: max(0px)) { | ||
.toolbar { | ||
height: calc(60px + env(safe-area-inset-bottom)); | ||
padding-bottom: max(env(safe-area-inset-bottom), 0px); | ||
} | ||
} :host { | ||
display: block; | ||
min-height: 100vh; | ||
padding-bottom: 60px; | ||
background: #f5f5f7; | ||
} | ||
.chat-container { | ||
max-width: min(90vw, 800px); | ||
margin: 0 auto; | ||
padding: clamp(1rem, 5vw, 2rem); | ||
} | ||
.message { | ||
margin-bottom: 1.5rem; | ||
padding: 1rem; | ||
border-radius: 12px; | ||
box-shadow: 0 2px 8px rgb(0 0 0 / 10%); | ||
} | ||
.user-message { | ||
margin-left: 2rem; | ||
background: #007bff; | ||
color: white; | ||
} | ||
.ai-message { | ||
margin-right: 2rem; | ||
background: white; | ||
color: #333; | ||
} | ||
.message-header { | ||
margin-bottom: 0.5rem; | ||
font-weight: 500; | ||
font-size: 0.9rem; | ||
opacity: 0.8; | ||
} | ||
.message-content { | ||
line-height: 1.5; | ||
} | ||
/* Bottom Toolbar Styles */ | ||
.toolbar { | ||
position: fixed; | ||
right: 0; | ||
bottom: 0; | ||
left: 0; | ||
z-index: 1000; | ||
display: flex; | ||
justify-content: space-around; | ||
align-items: center; | ||
height: 60px; | ||
padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) | ||
env(safe-area-inset-left); | ||
background: #fff; | ||
box-shadow: 0 -2px 10px rgb(0 0 0 / 10%); | ||
} | ||
.toolbar a { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
padding: 8px; | ||
color: #666; | ||
font-size: 0.75rem; | ||
text-decoration: none; | ||
user-select: none; | ||
transition: color 0.2s; | ||
-webkit-tap-highlight-color: transparent; | ||
} | ||
.toolbar svg { | ||
width: 24px; | ||
height: 24px; | ||
margin-bottom: 4px; | ||
} | ||
`; | ||
|
||
render() { | ||
return html` | ||
<div class="chat-container"> | ||
<div class="message user-message"> | ||
<div class="message-header">You</div> | ||
<div class="message-content">${this.userPrompt}</div> | ||
</div> | ||
<div class="message ai-message"> | ||
<div class="message-header">AI</div> | ||
<div class="message-content">${this.aiResponse}</div> | ||
</div> | ||
</div> | ||
<nav class="toolbar"> | ||
<a href="/"> | ||
<svg viewBox="0 0 24 24" fill="currentColor"> | ||
<path | ||
d="M12 2L2 12h3v8h6v-6h2v6h6v-8h3L12 2zm0 2.84L19.5 12h-1.5v8h-4v-6H10v6H6v-8H4.5L12 4.84z" | ||
/> | ||
</svg> | ||
Home | ||
</a> | ||
<a href="/user"> | ||
<svg viewBox="0 0 24 24" fill="currentColor"> | ||
<path | ||
d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0-6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm0 7c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4zm6 5H6v-.99c.2-.72 3.3-2.01 6-2.01s5.8 1.29 6 2v1z" | ||
/> | ||
</svg> | ||
User | ||
</a> | ||
</nav> | ||
`; | ||
} | ||
} |
Oops, something went wrong.