cordova
Valerie 2022-07-25 03:33:49 -04:00
parent e2ae16bd2c
commit 3cbac09f57
21 changed files with 7762 additions and 503 deletions

View File

@ -20,7 +20,8 @@
],
"ignorePatterns": [
"node_modules/**",
"**/dist/**"
"**/dist/**",
"cordova/**"
],
"rules": {
"@typescript-eslint/no-unused-vars": "error",

7615
cordova/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,19 +5,23 @@
"description": "A sample Apache Cordova application that responds to the deviceready event.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"cordova": "cordova"
},
"keywords": [
"ecosystem:cordova"
],
"author": "Apache Cordova Team",
"license": "Apache-2.0",
"devDependencies": {
"cordova-android": "^10.1.2"
},
"cordova": {
"platforms": [
"android"
]
},
"dependencies": {
"cordova": "^11.0.0"
},
"devDependencies": {
"cordova-android": "^10.1.2"
}
}

41
cordova/www/app.js vendored 100644

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,110 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
}
body {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
background-color:#E4E4E4;
background-image:linear-gradient(to bottom, #A7A7A7 0%, #E4E4E4 51%);
font-family: system-ui, -apple-system, -apple-system-font, 'Segoe UI', 'Roboto', sans-serif;
font-size:12px;
height:100vh;
margin:0px;
padding:0px;
/* Padding to avoid the "unsafe" areas behind notches in the screen */
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
text-transform:uppercase;
width:100%;
}
/* Portrait layout (default) */
.app {
background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
position:absolute; /* position in the center of the screen */
left:50%;
top:50%;
height:50px; /* text area height */
width:225px; /* text area width */
text-align:center;
padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
/* offset horizontal: half of text area width */
}
/* Landscape layout (with min-width) */
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
.app {
background-position:left center;
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
/* offset horizontal: half of image width and text area width */
}
}
h1 {
font-size:24px;
font-weight:normal;
margin:0px;
overflow:visible;
padding:0px;
text-align:center;
}
.event {
border-radius:4px;
color:#FFFFFF;
font-size:12px;
margin:0px 30px;
padding:2px 0px;
}
.event.listening {
background-color:#333333;
display:block;
}
.event.received {
background-color:#4B946A;
display:none;
}
#deviceready.ready .event.listening { display: none; }
#deviceready.ready .event.received { display: block; }
@keyframes fade {
from { opacity: 1.0; }
50% { opacity: 0.4; }
to { opacity: 1.0; }
}
.blink {
animation:fade 3000ms infinite;
-webkit-animation:fade 3000ms infinite;
}
@media screen and (prefers-color-scheme: dark) {
body {
background-image:linear-gradient(to bottom, #585858 0%, #1B1B1B 51%);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,50 +1,35 @@
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<meta charset="utf-8">
<!--
Customize this policy to fit your own app's needs. For more guidance, please refer to the docs:
https://cordova.apache.org/docs/en/latest/
Some notes:
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
* Enable inline JS: add 'unsafe-inline' to default-src
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<link rel="stylesheet" href="css/index.css">
<title>Hello World</title>
</head>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
</div>
</div>
<script src="cordova.js"></script>
<script src="js/index.js"></script>
</body>
<head>
<meta charset="utf-8">
<!--
Customize this policy to fit your own app's needs. For more guidance, please refer to the docs:
https://cordova.apache.org/docs/en/latest/
Some notes:
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
* Enable inline JS: add 'unsafe-inline' to default-src
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:; connect-src *;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="color-scheme" content="light dark">
<title>Hello World</title>
<style>
html, body {
overflow-x: hidden;
}
body {
position: relative
}
</style>
</head>
<body style="margin: 0px; overflow: hidden; color: #f8f8f2; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif">
<div id="app" style="width: 100vw; height: 100vh; background: #282a36"></div>
<script src="cordova.js"></script>
<script src="index.js"></script>
</body>
</html>

18
cordova/www/index.js vendored 100644
View File

@ -0,0 +1,18 @@
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
// alert(cordova.platformId + " " + cordova.version);
var my_awesome_script = document.createElement('script');
my_awesome_script.setAttribute('src', 'app.js');
my_awesome_script.setAttribute('type', 'module');
my_awesome_script.setAttribute('crossorigin', true);
document.head.appendChild(my_awesome_script);
}

View File

@ -1,29 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Wait for the deviceready event before using any of Cordova's device APIs.
// See https://cordova.apache.org/docs/en/latest/cordova/events/events.html#deviceready
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
// Cordova is now initialized. Have fun!
console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
document.getElementById('deviceready').classList.add('ready');
}

View File

@ -2,5 +2,5 @@
* @module preload
*/
export { getClientId, setClientId } from './clientId';
export { getClientId, setClientId } from './clientId';
export {versions} from './versions';

View File

@ -6,7 +6,7 @@
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Vite App</title>
</head>
<body style="margin: 0px; overflow: hidden; color: #f8f8f2; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif">
<body style="font-size: 1em; margin: 0px; overflow: hidden; color: #f8f8f2; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif">
<div id="app" style="width: 100vw; height: 100vh; background: #282a36"></div>
<script src="./src/index.tsx" type="module"></script>
</body>

View File

@ -0,0 +1,89 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import useMediaQuery from '../lib/useMediaQueries';
export default function Sidebar(props: {
threshold: number,
sidebar: number,
children: any[]
}) {
const bigScreen = useMediaQuery('(min-width:' + props.threshold + 'px)');
const [screenRef, setScreenRef] = useState<HTMLDivElement | null>(null);
const [startDrag, setStartDrag] = useState(0);
const [currentDrag, setCurrentDrag] = useState(0);
const [dragging, setDragging] = useState(false);
const [opened, setOpened] = useState(false);
const difference = opened ?
Math.min(currentDrag - startDrag, 0) :
Math.max(currentDrag - startDrag, 0);
const pointerDown = useCallback((e: any) => {
setDragging(true);
setStartDrag(e.touches[0].clientX);
setCurrentDrag(e.touches[0].clientX);
}, [dragging, startDrag, currentDrag]);
const pointerUp = useCallback(() => {
setDragging(false);
if(difference > 0) {
setOpened(true);
} else if (difference < 0) {
setOpened(false);
}
}, [dragging, currentDrag, startDrag, opened]);
const pointerMove = useCallback((e: any) => {
setCurrentDrag(e.touches[0].clientX);
}, [dragging, currentDrag]);
useEffect(() => {
if(screenRef === null) return;
screenRef.addEventListener('touchstart', pointerDown);
screenRef.addEventListener('touchend', pointerUp);
screenRef.addEventListener('touchmove', pointerMove);
// screenRef.addEventListener('pointercancel', pointerUp);
return () => {
screenRef.removeEventListener('touchstart', pointerDown);
screenRef.removeEventListener('touchend', pointerUp);
screenRef.removeEventListener('touchmove', pointerMove);
// screenRef.removeEventListener('pointercancel', pointerUp);
};
}, [screenRef, pointerUp, pointerDown]);
return <div ref={setScreenRef} style={{
width: '100%',
height: '100%',
position: 'relative',
userSelect: 'none',
// overflow: 'hidden',
}}>
<div
style={{
// background: 'red',
width: bigScreen ? (props.sidebar + 'px') : '100%',
height: '100%',
display: 'inline-block',
position: 'absolute',
top: '0px',
left: bigScreen ? '0px' : !dragging ? (opened ? '0px' : '-100%') : `calc(${difference}px ${opened ? '' : '- 100%'})`,
zIndex: '1',
transition: dragging ? 'none' : 'left 300ms linear, width 300ms linear',
}}
>{props.children[0]}</div>
<div
style={{
// background: 'green',
width: bigScreen ? 'calc(100% - ' + props.sidebar + 'px)' : '100%',
height: '100%',
display: 'inline-block',
position: 'absolute',
top: '0px',
left: bigScreen ? (props.sidebar + 'px') : '0px',
zIndex: '0',
transition: 'left 300ms linear, width 300ms linear',
}}
>{props.children[1]}</div>
</div>;
}

View File

@ -1,5 +1,6 @@
import React, { createContext } from 'react';
import React from 'react';
import ReactDOM from 'react-dom';
import Sidebar from './components/Sidebar';
import App from './pages/App';
ReactDOM.render(

View File

@ -0,0 +1,28 @@
import * as preload from '#preload';
const functions: any = (function() {
const electron = !!preload.getClientId;
const cordova = 'cordova' in globalThis;
console.log(preload);
// alert('Electron: ' + electron + '\nCordova: ' + cordova);
if(electron) {
return preload;
} else {
let cid: any = null;
return {
getClientId() {
return cid;
},
setClientId(id: any) {
cid = id;
},
};
}
})();
export const getClientId = functions.getClientId;
export const setClientId = functions.setClientId;

View File

@ -0,0 +1,43 @@
import { useEffect, useState } from 'react';
function useMediaQuery(query: string): boolean {
const getMatches = (query: string): boolean => {
// Prevents SSR issues
if (typeof window !== 'undefined') {
return window.matchMedia(query).matches;
}
return false;
};
const [matches, setMatches] = useState<boolean>(getMatches(query));
function handleChange() {
setMatches(getMatches(query));
}
useEffect(() => {
const matchMedia = window.matchMedia(query);
// Triggered at the first client-side load and if query changes
handleChange();
// Listen matchMedia
if (matchMedia.addListener) {
matchMedia.addListener(handleChange);
} else {
matchMedia.addEventListener('change', handleChange);
}
return () => {
if (matchMedia.removeListener) {
matchMedia.removeListener(handleChange);
} else {
matchMedia.removeEventListener('change', handleChange);
}
};
}, [query]);
return matches;
}
export default useMediaQuery;

View File

@ -1,8 +1,9 @@
import { createContext, useEffect, useState } from 'react';
import Channels from './Channels';
import Chat from './Chat';
import { getClientId, setClientId } from '#preload';
import { getClientId, setClientId } from '../lib/native';
import { useApi } from '../lib/useApi';
import Sidebar from '../components/Sidebar';
export const channelContext = createContext<{
channel: string | null,
@ -39,7 +40,14 @@ export default function App() {
return (
<clientIdContext.Provider value={clientId}>
<channelContext.Provider value={channelContextValue}>
<div style={{
<Sidebar
threshold={800}
sidebar={300}
>
<Channels></Channels>
<Chat></Chat>
</Sidebar>
{/* <div style={{
display: 'grid',
gridTemplateColumns: '200px 1fr',
gridTemplateRows: '1fr',
@ -49,12 +57,10 @@ export default function App() {
background: '#21222c',
borderRight: '1px solid #bd93f9',
}}>
<Channels></Channels>
</div>
<div>
<Chat></Chat>
</div>
</div>
</div> */}
</channelContext.Provider>
</clientIdContext.Provider>
);

View File

@ -83,7 +83,10 @@ export default function Channels() {
}, []);
return (
<>
<div style={{
height: '100%',
background: '#21222c',
}}>
<br></br>
{channels.map(c => (
<div key={c.uid} style={{
@ -133,6 +136,6 @@ export default function Channels() {
// lineHeight: '20px'
}}>ADD</button>
<NameTextbox></NameTextbox>
</>
</div>
);
}

View File

@ -63,83 +63,81 @@ export default () => {
}, [sendMessage]);
return (
<>
<div
style={{
height: '100%',
width: '100%',
display: 'grid',
gridTemplateColumns: '1fr 64px',
gridTemplateRows: '1fr 64px',
gridTemplateAreas: '"content content" "message send"',
}}
>
<div style={{
// borderBottom: '1px solid #bd93f9',
gridArea: 'content',
position: 'relative',
}}>
<div style={{
position: 'absolute',
bottom: '0px',
width: '100%',
}}>
{messages.map(message => (
<Message key={message.uid} message={message}></Message>
))}
</div>
</div>
<div onClick={() => {
textBoxRef.current?.focus();
}}style={{
margin: '8px',
marginRight: '3px',
borderRadius: '8px',
background: '#343746',
gridArea: 'message',
display: 'grid',
placeItems: 'center center',
padding: '0px 16px',
cursor: 'text',
overflow: 'auto',
}}>
<div
ref={textBoxRef}
onKeyDown={keyDown}
className="input"
role="textbox"
contentEditable
style={{
background: 'inherit',
outline: 'none',
boxSizing: 'border-box',
borderRadius: '8px',
width: '100%',
resize: 'none',
}}
></div>
</div>
<div
style={{
height: '100%',
width: '100%',
display: 'grid',
gridTemplateColumns: '1fr 64px',
gridTemplateRows: '1fr 64px',
gridTemplateAreas: '"content content" "message send"',
}}
>
<div style={{
// borderBottom: '1px solid #bd93f9',
gridArea: 'content',
position: 'relative',
}}>
<div style={{
position: 'absolute',
bottom: '0px',
width: '100%',
height: '100%',
padding: '8px',
boxSizing: 'border-box',
}}>
<div onClick={sendMessage} style={{
background: '#bd93f9',
width: '100%',
height: '100%',
// borderRadius: '50%',
borderRadius: '8px',
cursor: 'pointer',
display: 'grid',
placeItems: 'center center',
fontSize: '32px',
}}>
</div>
{messages.map(message => (
<Message key={message.uid} message={message}></Message>
))}
</div>
</div>
</>
<div onClick={() => {
textBoxRef.current?.focus();
}}style={{
margin: '8px',
marginRight: '3px',
borderRadius: '8px',
background: '#343746',
gridArea: 'message',
display: 'grid',
placeItems: 'center center',
padding: '0px 16px',
cursor: 'text',
overflow: 'auto',
}}>
<div
ref={textBoxRef}
onKeyDown={keyDown}
className="input"
role="textbox"
contentEditable
style={{
background: 'inherit',
outline: 'none',
boxSizing: 'border-box',
borderRadius: '8px',
width: '100%',
resize: 'none',
}}
></div>
</div>
<div style={{
width: '100%',
height: '100%',
padding: '8px',
boxSizing: 'border-box',
}}>
<div onClick={sendMessage} style={{
background: '#bd93f9',
width: '100%',
height: '100%',
// borderRadius: '50%',
borderRadius: '8px',
cursor: 'pointer',
display: 'grid',
placeItems: 'center center',
fontSize: '32px',
}}>
</div>
</div>
</div>
);
};

View File

@ -24,7 +24,7 @@ export function Message({
return (
<div style={{
display: 'grid',
gridTemplateColumns: '128px 1fr',
gridTemplateColumns: '4em 1fr',
width: '100%',
padding: '1px 0px',
}}>

View File

@ -0,0 +1,21 @@
#!/usr/bin/env node
const {execSync} = require('child_process');
const { copyFileSync, readdirSync } = require('fs');
const { resolve } = require('path');
execSync('npm run build');
const files = readdirSync(resolve('./packages/renderer/dist'));
files.forEach(file => {
if(file === 'index.html') return;
if(file.endsWith('.js.map'))
copyFileSync(resolve('./packages/renderer/dist/', file), './cordova/www/app.js.map');
if(file.endsWith('.js'))
copyFileSync(resolve('./packages/renderer/dist/', file), './cordova/www/app.js');
});
execSync('npm run cordova run', {
cwd: resolve('./cordova'),
});