Tina Tarighian commited on
Commit
128b839
Β·
1 Parent(s): 3fdfac3

mobile updates

Browse files
components/CameraSetup.js CHANGED
@@ -179,14 +179,13 @@ const CameraSetup = ({
179
  {isMobile && (
180
  <button
181
  onClick={switchCamera}
182
- className="absolute top-4 right-4 bg-white bg-opacity-70 p-2 rounded-full shadow-md z-10 hover:bg-opacity-90 transition-all"
183
  aria-label={`Switch to ${facingMode === 'user' ? 'back' : 'front'} camera`}
 
184
  >
185
- <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-gray-800" fill="none" viewBox="0 0 24 24" stroke="currentColor">
186
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
187
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
188
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.5 7.5L9.5 12.5" />
189
- </svg>
190
  </button>
191
  )}
192
  </>
 
179
  {isMobile && (
180
  <button
181
  onClick={switchCamera}
182
+ className="absolute top-4 right-4 bg-white bg-opacity-70 p-2 rounded-full shadow-md z-10 hover:bg-opacity-90 transition-all flex items-center justify-center"
183
  aria-label={`Switch to ${facingMode === 'user' ? 'back' : 'front'} camera`}
184
+ style={{ width: '40px', height: '40px' }}
185
  >
186
+ <span className="material-symbols-outlined text-gray-800" style={{ display: 'flex', lineHeight: 1 }}>
187
+ cameraswitch
188
+ </span>
 
 
189
  </button>
190
  )}
191
  </>
components/MainContent.js CHANGED
@@ -35,12 +35,15 @@ const MainContent = ({
35
  }) => {
36
  return (
37
  <>
38
- {/* Prompt Editor */}
39
- <PromptEditor
40
- customPrompt={customPrompt}
41
- setCustomPrompt={setCustomPrompt}
42
- isMac={isMac}
43
- />
 
 
 
44
 
45
  <div ref={containerRef} className="relative w-full max-w-4xl canvas-container">
46
  {/* Camera Setup */}
@@ -90,6 +93,16 @@ const MainContent = ({
90
  createPopParticles={createPopParticles}
91
  />
92
  </div>
 
 
 
 
 
 
 
 
 
 
93
  </>
94
  );
95
  };
 
35
  }) => {
36
  return (
37
  <>
38
+ {/* Prompt Editor - Only show above camera on desktop */}
39
+ {!isMobile && (
40
+ <PromptEditor
41
+ customPrompt={customPrompt}
42
+ setCustomPrompt={setCustomPrompt}
43
+ isMac={isMac}
44
+ isMobile={isMobile}
45
+ />
46
+ )}
47
 
48
  <div ref={containerRef} className="relative w-full max-w-4xl canvas-container">
49
  {/* Camera Setup */}
 
93
  createPopParticles={createPopParticles}
94
  />
95
  </div>
96
+
97
+ {/* Prompt Editor - Show below camera on mobile */}
98
+ {isMobile && (
99
+ <PromptEditor
100
+ customPrompt={customPrompt}
101
+ setCustomPrompt={setCustomPrompt}
102
+ isMac={isMac}
103
+ isMobile={isMobile}
104
+ />
105
+ )}
106
  </>
107
  );
108
  };
components/PromptEditor.js CHANGED
@@ -1,74 +1,100 @@
1
- import { useState } from 'react';
2
 
3
- const PromptEditor = ({ customPrompt, setCustomPrompt, isMac }) => {
4
  const [isEditingPrompt, setIsEditingPrompt] = useState(false);
5
  const [tempPrompt, setTempPrompt] = useState("");
 
 
 
 
 
 
6
 
7
  return (
8
- <div className="w-full max-w-4xl mb-4">
9
- <div className="flex justify-between items-center mb-1">
 
 
 
10
  <label htmlFor="system-prompt" className="block text-sm font-medium text-gray-700">
11
  System Prompt
12
  </label>
13
- {!isEditingPrompt ? (
14
- <button
15
- onClick={() => {
16
- setTempPrompt(customPrompt);
17
- setIsEditingPrompt(true);
18
- }}
19
- className="text-sm text-blue-600 hover:text-blue-800 flex items-center"
20
- >
21
- <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
22
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
23
- </svg>
24
- Edit
25
- </button>
26
- ) : null}
27
- </div>
28
-
29
- {isEditingPrompt ? (
30
- <div>
31
- <textarea
32
- id="system-prompt"
33
- value={tempPrompt}
34
- onChange={(e) => setTempPrompt(e.target.value)}
35
- onKeyDown={(e) => {
36
- // Save on Ctrl+Enter or Cmd+Enter
37
- if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
38
- e.preventDefault();
39
- setCustomPrompt(tempPrompt);
40
- setIsEditingPrompt(false);
41
- }
42
- }}
43
- className="w-full p-3 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm"
44
- rows={4}
45
- placeholder="Enter your custom prompt for Gemini..."
46
- />
47
- <div className="flex justify-end mt-2 space-x-2">
48
- <span className="text-xs text-gray-500 self-center mr-auto">
49
- Tip: Press {isMac ? '⌘' : 'Ctrl'}+Enter to save
50
- </span>
51
  <button
52
- onClick={() => setIsEditingPrompt(false)}
53
- className="px-3 py-1 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-100"
54
- >
55
- Cancel
56
- </button>
57
- <button
58
- onClick={() => {
59
- setCustomPrompt(tempPrompt);
60
- setIsEditingPrompt(false);
61
  }}
62
- className="px-3 py-1 text-sm text-white bg-blue-600 rounded-md hover:bg-blue-700"
63
  >
64
- Save
 
 
 
65
  </button>
66
- </div>
67
- </div>
68
- ) : (
69
- <div className="p-3 bg-gray-50 border border-gray-200 rounded-lg text-sm text-gray-800 whitespace-pre-wrap">
70
- {customPrompt}
 
 
 
 
 
 
71
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  )}
73
  </div>
74
  );
 
1
+ import { useState, useEffect } from 'react';
2
 
3
+ const PromptEditor = ({ customPrompt, setCustomPrompt, isMac, isMobile }) => {
4
  const [isEditingPrompt, setIsEditingPrompt] = useState(false);
5
  const [tempPrompt, setTempPrompt] = useState("");
6
+ const [isCollapsed, setIsCollapsed] = useState(isMobile); // Collapsed by default on mobile
7
+
8
+ // Update collapsed state if isMobile changes
9
+ useEffect(() => {
10
+ setIsCollapsed(isMobile);
11
+ }, [isMobile]);
12
 
13
  return (
14
+ <div className={`w-full max-w-4xl ${isMobile ? 'mt-4' : 'mb-4'}`}>
15
+ <div
16
+ className="flex justify-between items-center mb-1 cursor-pointer"
17
+ onClick={() => setIsCollapsed(!isCollapsed)}
18
+ >
19
  <label htmlFor="system-prompt" className="block text-sm font-medium text-gray-700">
20
  System Prompt
21
  </label>
22
+ <div className="flex items-center">
23
+ {!isEditingPrompt && !isCollapsed && (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  <button
25
+ onClick={(e) => {
26
+ e.stopPropagation(); // Prevent triggering the parent onClick
27
+ setTempPrompt(customPrompt);
28
+ setIsEditingPrompt(true);
 
 
 
 
 
29
  }}
30
+ className="text-sm text-blue-600 hover:text-blue-800 flex items-center mr-2"
31
  >
32
+ <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
33
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
34
+ </svg>
35
+ Edit
36
  </button>
37
+ )}
38
+ {/* Down/Up caret icon */}
39
+ <svg
40
+ xmlns="http://www.w3.org/2000/svg"
41
+ className={`h-5 w-5 text-gray-500 transition-transform duration-200 ${isCollapsed ? '' : 'transform rotate-180'}`}
42
+ fill="none"
43
+ viewBox="0 0 24 24"
44
+ stroke="currentColor"
45
+ >
46
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
47
+ </svg>
48
  </div>
49
+ </div>
50
+
51
+ {!isCollapsed && (
52
+ <>
53
+ {isEditingPrompt ? (
54
+ <div>
55
+ <textarea
56
+ id="system-prompt"
57
+ value={tempPrompt}
58
+ onChange={(e) => setTempPrompt(e.target.value)}
59
+ onKeyDown={(e) => {
60
+ // Save on Ctrl+Enter or Cmd+Enter
61
+ if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
62
+ e.preventDefault();
63
+ setCustomPrompt(tempPrompt);
64
+ setIsEditingPrompt(false);
65
+ }
66
+ }}
67
+ className="w-full p-3 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm"
68
+ rows={4}
69
+ placeholder="Enter your custom prompt for Gemini..."
70
+ />
71
+ <div className="flex justify-end mt-2 space-x-2">
72
+ <span className="text-xs text-gray-500 self-center mr-auto">
73
+ Tip: Press {isMac ? '⌘' : 'Ctrl'}+Enter to save
74
+ </span>
75
+ <button
76
+ onClick={() => setIsEditingPrompt(false)}
77
+ className="px-3 py-1 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-100"
78
+ >
79
+ Cancel
80
+ </button>
81
+ <button
82
+ onClick={() => {
83
+ setCustomPrompt(tempPrompt);
84
+ setIsEditingPrompt(false);
85
+ }}
86
+ className="px-3 py-1 text-sm text-white bg-blue-600 rounded-md hover:bg-blue-700"
87
+ >
88
+ Save
89
+ </button>
90
+ </div>
91
+ </div>
92
+ ) : (
93
+ <div className="p-3 bg-gray-50 border border-gray-200 rounded-lg text-sm text-gray-800 whitespace-pre-wrap">
94
+ {customPrompt}
95
+ </div>
96
+ )}
97
+ </>
98
  )}
99
  </div>
100
  );
components/ThoughtBubble.js CHANGED
@@ -48,10 +48,10 @@ const ThoughtBubble = ({
48
  <span
49
  style={{
50
  fontSize: isMobile ? '28px' : '36px',
51
- animation: 'thinking-blink 1.5s ease-in-out infinite'
52
  }}
53
  >
54
- πŸ€”
55
  </span>
56
  );
57
  }
 
48
  <span
49
  style={{
50
  fontSize: isMobile ? '28px' : '36px',
51
+ animation: 'thinking-spin 1.5s linear infinite'
52
  }}
53
  >
54
+ πŸ’­
55
  </span>
56
  );
57
  }
components/UIUtils.js CHANGED
@@ -52,6 +52,11 @@ export const AnimationStyles = () => {
52
  50% { opacity: 0.7; transform: scale(0.95); }
53
  }
54
 
 
 
 
 
 
55
  @keyframes spring-out {
56
  0% {
57
  transform: scale(0) translateY(0);
 
52
  50% { opacity: 0.7; transform: scale(0.95); }
53
  }
54
 
55
+ @keyframes thinking-spin {
56
+ 0% { transform: rotate(0deg); }
57
+ 100% { transform: rotate(360deg); }
58
+ }
59
+
60
  @keyframes spring-out {
61
  0% {
62
  transform: scale(0) translateY(0);
pages/_document.js CHANGED
@@ -3,7 +3,12 @@ import { Html, Head, Main, NextScript } from "next/document";
3
  export default function Document() {
4
  return (
5
  <Html lang="en">
6
- <Head />
 
 
 
 
 
7
  <body className="antialiased">
8
  <Main />
9
  <NextScript />
 
3
  export default function Document() {
4
  return (
5
  <Html lang="en">
6
+ <Head>
7
+ <link
8
+ rel="stylesheet"
9
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&icon_names=cameraswitch"
10
+ />
11
+ </Head>
12
  <body className="antialiased">
13
  <Main />
14
  <NextScript />