Compare commits
2 Commits
notificati
...
sql-wa-sql
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d7bc5f728 | |||
| 753d178fc3 |
@@ -1,310 +0,0 @@
|
|||||||
# Cursor Markdown Ruleset for TimeSafari Documentation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This ruleset enforces consistent markdown formatting standards across all project
|
|
||||||
documentation, ensuring readability, maintainability, and compliance with
|
|
||||||
markdownlint best practices.
|
|
||||||
|
|
||||||
## General Formatting Standards
|
|
||||||
|
|
||||||
### Line Length
|
|
||||||
|
|
||||||
- **Maximum line length**: 80 characters
|
|
||||||
- **Exception**: Code blocks (JSON, shell, TypeScript, etc.) - no line length
|
|
||||||
enforcement
|
|
||||||
- **Rationale**: Ensures readability across different screen sizes and terminal
|
|
||||||
widths
|
|
||||||
|
|
||||||
### Blank Lines
|
|
||||||
|
|
||||||
- **Headings**: Must be surrounded by blank lines above and below
|
|
||||||
- **Lists**: Must be surrounded by blank lines above and below
|
|
||||||
- **Code blocks**: Must be surrounded by blank lines above and below
|
|
||||||
- **Maximum consecutive blank lines**: 1 (no multiple blank lines)
|
|
||||||
- **File start**: No blank lines at the beginning of the file
|
|
||||||
- **File end**: Single newline character at the end
|
|
||||||
|
|
||||||
### Whitespace
|
|
||||||
|
|
||||||
- **No trailing spaces**: Remove all trailing whitespace from lines
|
|
||||||
- **No tabs**: Use spaces for indentation
|
|
||||||
- **Consistent indentation**: 2 spaces for list items and nested content
|
|
||||||
|
|
||||||
## Heading Standards
|
|
||||||
|
|
||||||
### Format
|
|
||||||
|
|
||||||
- **Style**: ATX-style headings (`#`, `##`, `###`, etc.)
|
|
||||||
- **Case**: Title case for general headings
|
|
||||||
- **Code references**: Use backticks for file names and technical terms
|
|
||||||
- ✅ `### Current package.json Scripts`
|
|
||||||
- ❌ `### Current Package.json Scripts`
|
|
||||||
|
|
||||||
### Hierarchy
|
|
||||||
|
|
||||||
- **H1 (#)**: Document title only
|
|
||||||
- **H2 (##)**: Major sections
|
|
||||||
- **H3 (###)**: Subsections
|
|
||||||
- **H4 (####)**: Sub-subsections
|
|
||||||
- **H5+**: Avoid deeper nesting
|
|
||||||
|
|
||||||
## List Standards
|
|
||||||
|
|
||||||
### Unordered Lists
|
|
||||||
|
|
||||||
- **Marker**: Use `-` (hyphen) consistently
|
|
||||||
- **Indentation**: 2 spaces for nested items
|
|
||||||
- **Blank lines**: Surround lists with blank lines
|
|
||||||
|
|
||||||
### Ordered Lists
|
|
||||||
|
|
||||||
- **Format**: `1.`, `2.`, `3.` (sequential numbering)
|
|
||||||
- **Indentation**: 2 spaces for nested items
|
|
||||||
- **Blank lines**: Surround lists with blank lines
|
|
||||||
|
|
||||||
### Task Lists
|
|
||||||
|
|
||||||
- **Format**: `- [ ]` for incomplete, `- [x]` for complete
|
|
||||||
- **Use case**: Project planning, checklists, implementation tracking
|
|
||||||
|
|
||||||
## Code Block Standards
|
|
||||||
|
|
||||||
### Fenced Code Blocks
|
|
||||||
|
|
||||||
- **Syntax**: Triple backticks with language specification
|
|
||||||
- **Languages**: `json`, `bash`, `typescript`, `javascript`, `yaml`, `markdown`
|
|
||||||
- **Blank lines**: Must be surrounded by blank lines above and below
|
|
||||||
- **Line length**: No enforcement within code blocks
|
|
||||||
|
|
||||||
### Inline Code
|
|
||||||
|
|
||||||
- **Format**: Single backticks for inline code references
|
|
||||||
- **Use case**: File names, commands, variables, properties
|
|
||||||
|
|
||||||
## Special Content Standards
|
|
||||||
|
|
||||||
### JSON Examples
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"property": "value",
|
|
||||||
"nested": {
|
|
||||||
"property": "value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Shell Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Command with comment
|
|
||||||
npm run build:web
|
|
||||||
|
|
||||||
# Multi-line command
|
|
||||||
VITE_GIT_HASH=`git log -1 --pretty=format:%h` \
|
|
||||||
vite build --config vite.config.web.mts
|
|
||||||
```
|
|
||||||
|
|
||||||
### TypeScript Examples
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Function with JSDoc
|
|
||||||
/**
|
|
||||||
* Get environment configuration
|
|
||||||
* @param env - Environment name
|
|
||||||
* @returns Environment config object
|
|
||||||
*/
|
|
||||||
const getEnvironmentConfig = (env: string) => {
|
|
||||||
switch (env) {
|
|
||||||
case 'prod':
|
|
||||||
return { /* production settings */ };
|
|
||||||
default:
|
|
||||||
return { /* development settings */ };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## File Structure Standards
|
|
||||||
|
|
||||||
### Document Header
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Document Title
|
|
||||||
|
|
||||||
**Author**: Matthew Raymer
|
|
||||||
**Date**: YYYY-MM-DD
|
|
||||||
**Status**: 🎯 **STATUS** - Brief description
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Brief description of the document's purpose and scope.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Section Organization
|
|
||||||
|
|
||||||
1. **Overview/Introduction**
|
|
||||||
2. **Current State Analysis**
|
|
||||||
3. **Implementation Plan**
|
|
||||||
4. **Technical Details**
|
|
||||||
5. **Testing & Validation**
|
|
||||||
6. **Next Steps**
|
|
||||||
|
|
||||||
## Markdownlint Configuration
|
|
||||||
|
|
||||||
### Required Rules
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"MD013": { "code_blocks": false },
|
|
||||||
"MD012": true,
|
|
||||||
"MD022": true,
|
|
||||||
"MD031": true,
|
|
||||||
"MD032": true,
|
|
||||||
"MD047": true,
|
|
||||||
"MD009": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rule Explanations
|
|
||||||
|
|
||||||
- **MD013**: Line length (disabled for code blocks)
|
|
||||||
- **MD012**: No multiple consecutive blank lines
|
|
||||||
- **MD022**: Headings should be surrounded by blank lines
|
|
||||||
- **MD031**: Fenced code blocks should be surrounded by blank lines
|
|
||||||
- **MD032**: Lists should be surrounded by blank lines
|
|
||||||
- **MD047**: Files should end with a single newline
|
|
||||||
- **MD009**: No trailing spaces
|
|
||||||
|
|
||||||
## Validation Commands
|
|
||||||
|
|
||||||
### Check Single File
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx markdownlint docs/filename.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check All Documentation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx markdownlint docs/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Auto-fix Common Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Remove trailing spaces
|
|
||||||
sed -i 's/[[:space:]]*$//' docs/filename.md
|
|
||||||
|
|
||||||
# Remove multiple blank lines
|
|
||||||
sed -i '/^$/N;/^\n$/D' docs/filename.md
|
|
||||||
|
|
||||||
# Add newline at end if missing
|
|
||||||
echo "" >> docs/filename.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
### Implementation Plans
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## Implementation Plan
|
|
||||||
|
|
||||||
### Phase 1: Foundation (Day 1)
|
|
||||||
|
|
||||||
#### 1.1 Component Setup
|
|
||||||
|
|
||||||
- [ ] Create new component file
|
|
||||||
- [ ] Add basic structure
|
|
||||||
- [ ] Implement core functionality
|
|
||||||
|
|
||||||
#### 1.2 Configuration
|
|
||||||
|
|
||||||
- [ ] Update configuration files
|
|
||||||
- [ ] Add environment variables
|
|
||||||
- [ ] Test configuration loading
|
|
||||||
```
|
|
||||||
|
|
||||||
### Status Tracking
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
**Status**: ✅ **COMPLETE** - All phases finished
|
|
||||||
**Progress**: 75% (15/20 components)
|
|
||||||
**Next**: Ready for testing phase
|
|
||||||
```
|
|
||||||
|
|
||||||
### Performance Metrics
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
#### 📊 Performance Metrics
|
|
||||||
- **Build Time**: 2.3 seconds (50% faster than baseline)
|
|
||||||
- **Bundle Size**: 1.2MB (30% reduction)
|
|
||||||
- **Success Rate**: 100% (no failures in 50 builds)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
### Pre-commit Hooks
|
|
||||||
|
|
||||||
- Run markdownlint on all changed markdown files
|
|
||||||
- Block commits with linting violations
|
|
||||||
- Auto-fix common issues when possible
|
|
||||||
|
|
||||||
### CI/CD Integration
|
|
||||||
|
|
||||||
- Include markdownlint in build pipeline
|
|
||||||
- Generate reports for documentation quality
|
|
||||||
- Fail builds with critical violations
|
|
||||||
|
|
||||||
### Team Guidelines
|
|
||||||
|
|
||||||
- All documentation PRs must pass markdownlint
|
|
||||||
- Use provided templates for new documents
|
|
||||||
- Follow established patterns for consistency
|
|
||||||
|
|
||||||
## Templates
|
|
||||||
|
|
||||||
### New Document Template
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Document Title
|
|
||||||
|
|
||||||
**Author**: Matthew Raymer
|
|
||||||
**Date**: YYYY-MM-DD
|
|
||||||
**Status**: 🎯 **PLANNING** - Ready for Implementation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Brief description of the document's purpose and scope.
|
|
||||||
|
|
||||||
## Current State
|
|
||||||
|
|
||||||
Description of current situation or problem.
|
|
||||||
|
|
||||||
## Implementation Plan
|
|
||||||
|
|
||||||
### Phase 1: Foundation
|
|
||||||
|
|
||||||
- [ ] Task 1
|
|
||||||
- [ ] Task 2
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. **Review and approve plan**
|
|
||||||
2. **Begin implementation**
|
|
||||||
3. **Test and validate**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Status**: Ready for implementation
|
|
||||||
**Priority**: Medium
|
|
||||||
**Estimated Effort**: X days
|
|
||||||
**Dependencies**: None
|
|
||||||
**Stakeholders**: Development team
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Last Updated**: 2025-07-09
|
|
||||||
**Version**: 1.0
|
|
||||||
**Maintainer**: Matthew Raymer
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
---
|
|
||||||
description:
|
|
||||||
globs:
|
|
||||||
alwaysApply: true
|
|
||||||
---
|
|
||||||
# Absurd SQL - Cursor Development Guide
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
Absurd SQL is a backend implementation for sql.js that enables persistent SQLite databases in the browser by using IndexedDB as a block storage system. This guide provides rules and best practices for developing with this project in Cursor.
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
```
|
|
||||||
absurd-sql/
|
|
||||||
├── src/ # Source code
|
|
||||||
├── dist/ # Built files
|
|
||||||
├── package.json # Dependencies and scripts
|
|
||||||
├── rollup.config.js # Build configuration
|
|
||||||
└── jest.config.js # Test configuration
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development Rules
|
|
||||||
|
|
||||||
### 1. Worker Thread Requirements
|
|
||||||
- All SQL operations MUST be performed in a worker thread
|
|
||||||
- Main thread should only handle worker initialization and communication
|
|
||||||
- Never block the main thread with database operations
|
|
||||||
|
|
||||||
### 2. Code Organization
|
|
||||||
- Keep worker code in separate files (e.g., `*.worker.js`)
|
|
||||||
- Use ES modules for imports/exports
|
|
||||||
- Follow the project's existing module structure
|
|
||||||
|
|
||||||
### 3. Required Headers
|
|
||||||
When developing locally or deploying, ensure these headers are set:
|
|
||||||
```
|
|
||||||
Cross-Origin-Opener-Policy: same-origin
|
|
||||||
Cross-Origin-Embedder-Policy: require-corp
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Browser Compatibility
|
|
||||||
- Primary target: Modern browsers with SharedArrayBuffer support
|
|
||||||
- Fallback mode: Safari (with limitations)
|
|
||||||
- Always test in both modes
|
|
||||||
|
|
||||||
### 5. Database Configuration
|
|
||||||
Recommended database settings:
|
|
||||||
```sql
|
|
||||||
PRAGMA journal_mode=MEMORY;
|
|
||||||
PRAGMA page_size=8192; -- Optional, but recommended
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Development Workflow
|
|
||||||
1. Install dependencies:
|
|
||||||
```bash
|
|
||||||
yarn add @jlongster/sql.js absurd-sql
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Development commands:
|
|
||||||
- `yarn build` - Build the project
|
|
||||||
- `yarn jest` - Run tests
|
|
||||||
- `yarn serve` - Start development server
|
|
||||||
|
|
||||||
### 7. Testing Guidelines
|
|
||||||
- Write tests for both SharedArrayBuffer and fallback modes
|
|
||||||
- Use Jest for testing
|
|
||||||
- Include performance benchmarks for critical operations
|
|
||||||
|
|
||||||
### 8. Performance Considerations
|
|
||||||
- Use bulk operations when possible
|
|
||||||
- Monitor read/write performance
|
|
||||||
- Consider using transactions for multiple operations
|
|
||||||
- Avoid unnecessary database connections
|
|
||||||
|
|
||||||
### 9. Error Handling
|
|
||||||
- Implement proper error handling for:
|
|
||||||
- Worker initialization failures
|
|
||||||
- Database connection issues
|
|
||||||
- Concurrent access conflicts (in fallback mode)
|
|
||||||
- Storage quota exceeded scenarios
|
|
||||||
|
|
||||||
### 10. Security Best Practices
|
|
||||||
- Never expose database operations directly to the client
|
|
||||||
- Validate all SQL queries
|
|
||||||
- Implement proper access controls
|
|
||||||
- Handle sensitive data appropriately
|
|
||||||
|
|
||||||
### 11. Code Style
|
|
||||||
- Follow ESLint configuration
|
|
||||||
- Use async/await for asynchronous operations
|
|
||||||
- Document complex database operations
|
|
||||||
- Include comments for non-obvious optimizations
|
|
||||||
|
|
||||||
### 12. Debugging
|
|
||||||
- Use `jest-debug` for debugging tests
|
|
||||||
- Monitor IndexedDB usage in browser dev tools
|
|
||||||
- Check worker communication in console
|
|
||||||
- Use performance monitoring tools
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
### Worker Initialization
|
|
||||||
```javascript
|
|
||||||
// Main thread
|
|
||||||
import { initBackend } from 'absurd-sql/dist/indexeddb-main-thread';
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
let worker = new Worker(new URL('./index.worker.js', import.meta.url));
|
|
||||||
initBackend(worker);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Setup
|
|
||||||
```javascript
|
|
||||||
// Worker thread
|
|
||||||
import initSqlJs from '@jlongster/sql.js';
|
|
||||||
import { SQLiteFS } from 'absurd-sql';
|
|
||||||
import IndexedDBBackend from 'absurd-sql/dist/indexeddb-backend';
|
|
||||||
|
|
||||||
async function setupDatabase() {
|
|
||||||
let SQL = await initSqlJs({ locateFile: file => file });
|
|
||||||
let sqlFS = new SQLiteFS(SQL.FS, new IndexedDBBackend());
|
|
||||||
SQL.register_for_idb(sqlFS);
|
|
||||||
|
|
||||||
SQL.FS.mkdir('/sql');
|
|
||||||
SQL.FS.mount(sqlFS, {}, '/sql');
|
|
||||||
|
|
||||||
return new SQL.Database('/sql/db.sqlite', { filename: true });
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
1. SharedArrayBuffer not available
|
|
||||||
- Check COOP/COEP headers
|
|
||||||
- Verify browser support
|
|
||||||
- Test fallback mode
|
|
||||||
|
|
||||||
2. Worker initialization failures
|
|
||||||
- Check file paths
|
|
||||||
- Verify module imports
|
|
||||||
- Check browser console for errors
|
|
||||||
|
|
||||||
3. Performance issues
|
|
||||||
- Monitor IndexedDB usage
|
|
||||||
- Check for unnecessary operations
|
|
||||||
- Verify transaction usage
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
- [Project Demo](https://priceless-keller-d097e5.netlify.app/)
|
|
||||||
- [Example Project](https://github.com/jlongster/absurd-example-project)
|
|
||||||
- [Blog Post](https://jlongster.com/future-sql-web)
|
|
||||||
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)
|
|
||||||
@@ -7,13 +7,13 @@ alwaysApply: true
|
|||||||
|
|
||||||
## 1. Platform Support Matrix
|
## 1. Platform Support Matrix
|
||||||
|
|
||||||
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) |
|
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) | PyWebView (Desktop) |
|
||||||
|---------|-----------|-------------------|-------------------|
|
|---------|-----------|-------------------|-------------------|-------------------|
|
||||||
| QR Code Scanning | WebInlineQRScanner | @capacitor-mlkit/barcode-scanning | Not Implemented |
|
| QR Code Scanning | WebInlineQRScanner | @capacitor-mlkit/barcode-scanning | Not Implemented | Not Implemented |
|
||||||
| Deep Linking | URL Parameters | App URL Open Events | Not Implemented |
|
| Deep Linking | URL Parameters | App URL Open Events | Not Implemented | Not Implemented |
|
||||||
| File System | Limited (Browser API) | Capacitor Filesystem | Electron fs |
|
| File System | Limited (Browser API) | Capacitor Filesystem | Electron fs | PyWebView Python Bridge |
|
||||||
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented |
|
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented | Not Implemented |
|
||||||
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks |
|
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks | process.env checks |
|
||||||
|
|
||||||
## 2. Project Structure
|
## 2. Project Structure
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ src/
|
|||||||
├── main.common.ts # Shared initialization
|
├── main.common.ts # Shared initialization
|
||||||
├── main.capacitor.ts # Mobile entry
|
├── main.capacitor.ts # Mobile entry
|
||||||
├── main.electron.ts # Electron entry
|
├── main.electron.ts # Electron entry
|
||||||
|
├── main.pywebview.ts # PyWebView entry
|
||||||
└── main.web.ts # Web/PWA entry
|
└── main.web.ts # Web/PWA entry
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -51,7 +52,9 @@ root/
|
|||||||
├── vite.config.common.mts # Shared config
|
├── vite.config.common.mts # Shared config
|
||||||
├── vite.config.capacitor.mts # Mobile build
|
├── vite.config.capacitor.mts # Mobile build
|
||||||
├── vite.config.electron.mts # Electron build
|
├── vite.config.electron.mts # Electron build
|
||||||
└── vite.config.web.mts # Web/PWA build
|
├── vite.config.pywebview.mts # PyWebView build
|
||||||
|
├── vite.config.web.mts # Web/PWA build
|
||||||
|
└── vite.config.utils.mts # Build utilities
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. Service Architecture
|
## 3. Service Architecture
|
||||||
@@ -65,7 +68,8 @@ services/
|
|||||||
├── platforms/ # Platform-specific services
|
├── platforms/ # Platform-specific services
|
||||||
│ ├── WebPlatformService.ts
|
│ ├── WebPlatformService.ts
|
||||||
│ ├── CapacitorPlatformService.ts
|
│ ├── CapacitorPlatformService.ts
|
||||||
│ └── ElectronPlatformService.ts
|
│ ├── ElectronPlatformService.ts
|
||||||
|
│ └── PyWebViewPlatformService.ts
|
||||||
└── factory/ # Service factories
|
└── factory/ # Service factories
|
||||||
└── PlatformServiceFactory.ts
|
└── PlatformServiceFactory.ts
|
||||||
```
|
```
|
||||||
@@ -149,7 +153,7 @@ export function createBuildConfig(mode: string) {
|
|||||||
return {
|
return {
|
||||||
define: {
|
define: {
|
||||||
'process.env.VITE_PLATFORM': JSON.stringify(mode),
|
'process.env.VITE_PLATFORM': JSON.stringify(mode),
|
||||||
// PWA is automatically enabled for web platforms via build configuration
|
'process.env.VITE_PWA_ENABLED': JSON.stringify(!isNative),
|
||||||
__IS_MOBILE__: JSON.stringify(isCapacitor),
|
__IS_MOBILE__: JSON.stringify(isCapacitor),
|
||||||
__USE_QR_READER__: JSON.stringify(!isCapacitor)
|
__USE_QR_READER__: JSON.stringify(!isCapacitor)
|
||||||
}
|
}
|
||||||
@@ -163,7 +167,8 @@ export function createBuildConfig(mode: string) {
|
|||||||
# Build commands from package.json
|
# Build commands from package.json
|
||||||
"build:web": "vite build --config vite.config.web.mts",
|
"build:web": "vite build --config vite.config.web.mts",
|
||||||
"build:capacitor": "vite build --config vite.config.capacitor.mts",
|
"build:capacitor": "vite build --config vite.config.capacitor.mts",
|
||||||
"build:electron": "vite build --config vite.config.electron.mts"
|
"build:electron": "vite build --config vite.config.electron.mts",
|
||||||
|
"build:pywebview": "vite build --config vite.config.pywebview.mts"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 6. Testing Strategy
|
## 6. Testing Strategy
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
description:
|
description:
|
||||||
globs:
|
globs:
|
||||||
alwaysApply: false
|
alwaysApply: true
|
||||||
---
|
---
|
||||||
# Camera Implementation Documentation
|
# Camera Implementation Documentation
|
||||||
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
description: rules used while developing
|
|
||||||
globs:
|
|
||||||
alwaysApply: true
|
|
||||||
---
|
|
||||||
✅ use system date command to timestamp all interactions with accurate date and time
|
|
||||||
✅ python script files must always have a blank line at their end
|
|
||||||
✅ remove whitespace at the end of lines
|
|
||||||
✅ use npm run lint-fix to check for warnings
|
|
||||||
✅ do not use npm run dev let me handle running and supplying feedback
|
|
||||||
✅ do not add or commit for the user; let him control that process
|
|
||||||
|
|
||||||
always preview changes and commit message to use and allow me to copy and paste
|
|
||||||
✅ Preferred Commit Message Format
|
|
||||||
|
|
||||||
Short summary in the first line (concise and high-level).
|
|
||||||
Avoid long commit bodies unless truly necessary.
|
|
||||||
|
|
||||||
✅ Valued Content in Commit Messages
|
|
||||||
|
|
||||||
Specific fixes or features.
|
|
||||||
Symptoms or problems that were fixed.
|
|
||||||
Notes about tests passing or TS/linting errors being resolved (briefly).
|
|
||||||
|
|
||||||
❌ Avoid in Commit Messages
|
|
||||||
|
|
||||||
Vague terms: “improved”, “enhanced”, “better” — especially from AI.
|
|
||||||
Minor changes: small doc tweaks, one-liners, cleanup, or lint fixes.
|
|
||||||
Redundant blurbs: repeated across files or too generic.
|
|
||||||
Multiple overlapping purposes in a single commit — prefer narrow, focused commits.
|
|
||||||
Long explanations of what can be deduced from good in-line code comments.
|
|
||||||
|
|
||||||
Guiding Principle
|
|
||||||
|
|
||||||
Let code and inline documentation speak for themselves. Use commits to highlight what isn't obvious from reading the code.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
description:
|
|
||||||
globs:
|
|
||||||
alwaysApply: true
|
|
||||||
---
|
|
||||||
All references in the codebase to Dexie apply only to migration from IndexedDb to Sqlite and will be deprecated in future versions.
|
|
||||||
@@ -1,314 +0,0 @@
|
|||||||
---
|
|
||||||
globs: *.md
|
|
||||||
alwaysApply: false
|
|
||||||
---
|
|
||||||
# Cursor Markdown Ruleset for TimeSafari Documentation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This ruleset enforces consistent markdown formatting standards across all project
|
|
||||||
documentation, ensuring readability, maintainability, and compliance with
|
|
||||||
markdownlint best practices.
|
|
||||||
|
|
||||||
## General Formatting Standards
|
|
||||||
|
|
||||||
### Line Length
|
|
||||||
|
|
||||||
- **Maximum line length**: 80 characters
|
|
||||||
- **Exception**: Code blocks (JSON, shell, TypeScript, etc.) - no line length
|
|
||||||
enforcement
|
|
||||||
- **Rationale**: Ensures readability across different screen sizes and terminal
|
|
||||||
widths
|
|
||||||
|
|
||||||
### Blank Lines
|
|
||||||
|
|
||||||
- **Headings**: Must be surrounded by blank lines above and below
|
|
||||||
- **Lists**: Must be surrounded by blank lines above and below
|
|
||||||
- **Code blocks**: Must be surrounded by blank lines above and below
|
|
||||||
- **Maximum consecutive blank lines**: 1 (no multiple blank lines)
|
|
||||||
- **File start**: No blank lines at the beginning of the file
|
|
||||||
- **File end**: Single newline character at the end
|
|
||||||
|
|
||||||
### Whitespace
|
|
||||||
|
|
||||||
- **No trailing spaces**: Remove all trailing whitespace from lines
|
|
||||||
- **No tabs**: Use spaces for indentation
|
|
||||||
- **Consistent indentation**: 2 spaces for list items and nested content
|
|
||||||
|
|
||||||
## Heading Standards
|
|
||||||
|
|
||||||
### Format
|
|
||||||
|
|
||||||
- **Style**: ATX-style headings (`#`, `##`, `###`, etc.)
|
|
||||||
- **Case**: Title case for general headings
|
|
||||||
- **Code references**: Use backticks for file names and technical terms
|
|
||||||
- ✅ `### Current package.json Scripts`
|
|
||||||
- ❌ `### Current Package.json Scripts`
|
|
||||||
|
|
||||||
### Hierarchy
|
|
||||||
|
|
||||||
- **H1 (#)**: Document title only
|
|
||||||
- **H2 (##)**: Major sections
|
|
||||||
- **H3 (###)**: Subsections
|
|
||||||
- **H4 (####)**: Sub-subsections
|
|
||||||
- **H5+**: Avoid deeper nesting
|
|
||||||
|
|
||||||
## List Standards
|
|
||||||
|
|
||||||
### Unordered Lists
|
|
||||||
|
|
||||||
- **Marker**: Use `-` (hyphen) consistently
|
|
||||||
- **Indentation**: 2 spaces for nested items
|
|
||||||
- **Blank lines**: Surround lists with blank lines
|
|
||||||
|
|
||||||
### Ordered Lists
|
|
||||||
|
|
||||||
- **Format**: `1.`, `2.`, `3.` (sequential numbering)
|
|
||||||
- **Indentation**: 2 spaces for nested items
|
|
||||||
- **Blank lines**: Surround lists with blank lines
|
|
||||||
|
|
||||||
### Task Lists
|
|
||||||
|
|
||||||
- **Format**: `- [ ]` for incomplete, `- [x]` for complete
|
|
||||||
- **Use case**: Project planning, checklists, implementation tracking
|
|
||||||
|
|
||||||
## Code Block Standards
|
|
||||||
|
|
||||||
### Fenced Code Blocks
|
|
||||||
|
|
||||||
- **Syntax**: Triple backticks with language specification
|
|
||||||
- **Languages**: `json`, `bash`, `typescript`, `javascript`, `yaml`, `markdown`
|
|
||||||
- **Blank lines**: Must be surrounded by blank lines above and below
|
|
||||||
- **Line length**: No enforcement within code blocks
|
|
||||||
|
|
||||||
### Inline Code
|
|
||||||
|
|
||||||
- **Format**: Single backticks for inline code references
|
|
||||||
- **Use case**: File names, commands, variables, properties
|
|
||||||
|
|
||||||
## Special Content Standards
|
|
||||||
|
|
||||||
### JSON Examples
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"property": "value",
|
|
||||||
"nested": {
|
|
||||||
"property": "value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Shell Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Command with comment
|
|
||||||
npm run build:web
|
|
||||||
|
|
||||||
# Multi-line command
|
|
||||||
VITE_GIT_HASH=`git log -1 --pretty=format:%h` \
|
|
||||||
vite build --config vite.config.web.mts
|
|
||||||
```
|
|
||||||
|
|
||||||
### TypeScript Examples
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Function with JSDoc
|
|
||||||
/**
|
|
||||||
* Get environment configuration
|
|
||||||
* @param env - Environment name
|
|
||||||
* @returns Environment config object
|
|
||||||
*/
|
|
||||||
const getEnvironmentConfig = (env: string) => {
|
|
||||||
switch (env) {
|
|
||||||
case 'prod':
|
|
||||||
return { /* production settings */ };
|
|
||||||
default:
|
|
||||||
return { /* development settings */ };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## File Structure Standards
|
|
||||||
|
|
||||||
### Document Header
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Document Title
|
|
||||||
|
|
||||||
**Author**: Matthew Raymer
|
|
||||||
**Date**: YYYY-MM-DD
|
|
||||||
**Status**: 🎯 **STATUS** - Brief description
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Brief description of the document's purpose and scope.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Section Organization
|
|
||||||
|
|
||||||
1. **Overview/Introduction**
|
|
||||||
2. **Current State Analysis**
|
|
||||||
3. **Implementation Plan**
|
|
||||||
4. **Technical Details**
|
|
||||||
5. **Testing & Validation**
|
|
||||||
6. **Next Steps**
|
|
||||||
|
|
||||||
## Markdownlint Configuration
|
|
||||||
|
|
||||||
### Required Rules
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"MD013": { "code_blocks": false },
|
|
||||||
"MD012": true,
|
|
||||||
"MD022": true,
|
|
||||||
"MD031": true,
|
|
||||||
"MD032": true,
|
|
||||||
"MD047": true,
|
|
||||||
"MD009": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rule Explanations
|
|
||||||
|
|
||||||
- **MD013**: Line length (disabled for code blocks)
|
|
||||||
- **MD012**: No multiple consecutive blank lines
|
|
||||||
- **MD022**: Headings should be surrounded by blank lines
|
|
||||||
- **MD031**: Fenced code blocks should be surrounded by blank lines
|
|
||||||
- **MD032**: Lists should be surrounded by blank lines
|
|
||||||
- **MD047**: Files should end with a single newline
|
|
||||||
- **MD009**: No trailing spaces
|
|
||||||
|
|
||||||
## Validation Commands
|
|
||||||
|
|
||||||
### Check Single File
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx markdownlint docs/filename.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check All Documentation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx markdownlint docs/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Auto-fix Common Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Remove trailing spaces
|
|
||||||
sed -i 's/[[:space:]]*$//' docs/filename.md
|
|
||||||
|
|
||||||
# Remove multiple blank lines
|
|
||||||
sed -i '/^$/N;/^\n$/D' docs/filename.md
|
|
||||||
|
|
||||||
# Add newline at end if missing
|
|
||||||
echo "" >> docs/filename.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
### Implementation Plans
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## Implementation Plan
|
|
||||||
|
|
||||||
### Phase 1: Foundation (Day 1)
|
|
||||||
|
|
||||||
#### 1.1 Component Setup
|
|
||||||
|
|
||||||
- [ ] Create new component file
|
|
||||||
- [ ] Add basic structure
|
|
||||||
- [ ] Implement core functionality
|
|
||||||
|
|
||||||
#### 1.2 Configuration
|
|
||||||
|
|
||||||
- [ ] Update configuration files
|
|
||||||
- [ ] Add environment variables
|
|
||||||
- [ ] Test configuration loading
|
|
||||||
```
|
|
||||||
|
|
||||||
### Status Tracking
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
**Status**: ✅ **COMPLETE** - All phases finished
|
|
||||||
**Progress**: 75% (15/20 components)
|
|
||||||
**Next**: Ready for testing phase
|
|
||||||
```
|
|
||||||
|
|
||||||
### Performance Metrics
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
#### 📊 Performance Metrics
|
|
||||||
- **Build Time**: 2.3 seconds (50% faster than baseline)
|
|
||||||
- **Bundle Size**: 1.2MB (30% reduction)
|
|
||||||
- **Success Rate**: 100% (no failures in 50 builds)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
### Pre-commit Hooks
|
|
||||||
|
|
||||||
- Run markdownlint on all changed markdown files
|
|
||||||
- Block commits with linting violations
|
|
||||||
- Auto-fix common issues when possible
|
|
||||||
|
|
||||||
### CI/CD Integration
|
|
||||||
|
|
||||||
- Include markdownlint in build pipeline
|
|
||||||
- Generate reports for documentation quality
|
|
||||||
- Fail builds with critical violations
|
|
||||||
|
|
||||||
### Team Guidelines
|
|
||||||
|
|
||||||
- All documentation PRs must pass markdownlint
|
|
||||||
- Use provided templates for new documents
|
|
||||||
- Follow established patterns for consistency
|
|
||||||
|
|
||||||
## Templates
|
|
||||||
|
|
||||||
### New Document Template
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Document Title
|
|
||||||
|
|
||||||
**Author**: Matthew Raymer
|
|
||||||
**Date**: YYYY-MM-DD
|
|
||||||
**Status**: 🎯 **PLANNING** - Ready for Implementation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Brief description of the document's purpose and scope.
|
|
||||||
|
|
||||||
## Current State
|
|
||||||
|
|
||||||
Description of current situation or problem.
|
|
||||||
|
|
||||||
## Implementation Plan
|
|
||||||
|
|
||||||
### Phase 1: Foundation
|
|
||||||
|
|
||||||
- [ ] Task 1
|
|
||||||
- [ ] Task 2
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. **Review and approve plan**
|
|
||||||
2. **Begin implementation**
|
|
||||||
3. **Test and validate**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Status**: Ready for implementation
|
|
||||||
**Priority**: Medium
|
|
||||||
**Estimated Effort**: X days
|
|
||||||
**Dependencies**: None
|
|
||||||
**Stakeholders**: Development team
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Last Updated**: 2025-07-09
|
|
||||||
**Version**: 1.0
|
|
||||||
**Maintainer**: Matthew Raymer
|
|
||||||
171
.dockerignore
@@ -1,171 +0,0 @@
|
|||||||
# TimeSafari Docker Ignore File
|
|
||||||
# Author: Matthew Raymer
|
|
||||||
# Description: Excludes unnecessary files from Docker build context
|
|
||||||
#
|
|
||||||
# Benefits:
|
|
||||||
# - Faster build times
|
|
||||||
# - Smaller build context
|
|
||||||
# - Reduced image size
|
|
||||||
# - Better security (excludes sensitive files)
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
node_modules
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# Build outputs
|
|
||||||
# dist - Allow dist directory for Docker builds (contains pre-built assets)
|
|
||||||
dist-*
|
|
||||||
build
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Development files
|
|
||||||
.git
|
|
||||||
.gitignore
|
|
||||||
README.md
|
|
||||||
CHANGELOG.md
|
|
||||||
CONTRIBUTING.md
|
|
||||||
BUILDING.md
|
|
||||||
LICENSE
|
|
||||||
|
|
||||||
# IDE and editor files
|
|
||||||
.vscode
|
|
||||||
.idea
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
*~
|
|
||||||
|
|
||||||
# OS generated files
|
|
||||||
.DS_Store
|
|
||||||
.DS_Store?
|
|
||||||
._*
|
|
||||||
.Spotlight-V100
|
|
||||||
.Trashes
|
|
||||||
ehthumbs.db
|
|
||||||
Thumbs.db
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
.env.local
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
.parcel-cache
|
|
||||||
|
|
||||||
# next.js build output
|
|
||||||
.next
|
|
||||||
|
|
||||||
# nuxt.js build output
|
|
||||||
.nuxt
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# TernJS port file
|
|
||||||
.tern-port
|
|
||||||
|
|
||||||
# Stores VSCode versions used for testing VSCode extensions
|
|
||||||
.vscode-test
|
|
||||||
|
|
||||||
# Test files
|
|
||||||
test-playwright
|
|
||||||
test-playwright-results
|
|
||||||
test-results
|
|
||||||
test-scripts
|
|
||||||
|
|
||||||
# Documentation
|
|
||||||
doc
|
|
||||||
|
|
||||||
# Scripts (keep only what's needed for build)
|
|
||||||
scripts/test-*.sh
|
|
||||||
scripts/*.js
|
|
||||||
scripts/README.md
|
|
||||||
|
|
||||||
# Platform-specific files
|
|
||||||
android
|
|
||||||
ios
|
|
||||||
electron
|
|
||||||
|
|
||||||
# Docker files (avoid recursive copying)
|
|
||||||
Dockerfile*
|
|
||||||
docker-compose*
|
|
||||||
.dockerignore
|
|
||||||
|
|
||||||
# CI/CD files
|
|
||||||
.github
|
|
||||||
.gitlab-ci.yml
|
|
||||||
.travis.yml
|
|
||||||
.circleci
|
|
||||||
|
|
||||||
# Temporary files
|
|
||||||
tmp
|
|
||||||
temp
|
|
||||||
|
|
||||||
# Backup files
|
|
||||||
*.bak
|
|
||||||
*.backup
|
|
||||||
|
|
||||||
# Archive files
|
|
||||||
*.tar
|
|
||||||
*.tar.gz
|
|
||||||
*.zip
|
|
||||||
*.rar
|
|
||||||
|
|
||||||
# Certificate files
|
|
||||||
*.pem
|
|
||||||
*.key
|
|
||||||
*.crt
|
|
||||||
*.p12
|
|
||||||
|
|
||||||
# Configuration files that might contain secrets
|
|
||||||
*.secrets
|
|
||||||
secrets.json
|
|
||||||
config.local.json
|
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
|
# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.
|
||||||
|
|
||||||
# iOS doesn't like spaces in the app title.
|
# iOS doesn't like spaces in the app title.
|
||||||
TIME_SAFARI_APP_TITLE="TimeSafari_Dev"
|
TIME_SAFARI_APP_TITLE="TimeSafari_Dev"
|
||||||
VITE_APP_SERVER=http://localhost:8080
|
VITE_APP_SERVER=http://localhost:3000
|
||||||
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
|
# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
|
||||||
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
|
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F
|
||||||
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
|
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
|
||||||
# Using shared server by default to ease setup, which works for shared test users.
|
# Using shared server by default to ease setup, which works for shared test users.
|
||||||
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
|
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
|
||||||
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000
|
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000
|
||||||
#VITE_DEFAULT_PUSH_SERVER... can't be set up with localhost domain
|
|
||||||
VITE_PASSKEYS_ENABLED=true
|
VITE_PASSKEYS_ENABLED=true
|
||||||
|
|||||||
6
.env.example
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Admin DID credentials
|
||||||
|
ADMIN_DID=did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F
|
||||||
|
ADMIN_PRIVATE_KEY=2b6472c026ec2aa2c4235c994a63868fc9212d18b58f6cbfe861b52e71330f5b
|
||||||
|
|
||||||
|
# API Configuration
|
||||||
|
ENDORSER_API_URL=https://test-api.endorser.ch/api/v2/claim
|
||||||
@@ -9,4 +9,3 @@ VITE_DEFAULT_ENDORSER_API_SERVER=https://api.endorser.ch
|
|||||||
|
|
||||||
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app
|
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app
|
||||||
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch
|
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch
|
||||||
VITE_DEFAULT_PUSH_SERVER=https://timesafari.app
|
|
||||||
|
|||||||
@@ -9,5 +9,4 @@ VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
|
|||||||
|
|
||||||
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
|
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app
|
||||||
VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch
|
VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch
|
||||||
VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app
|
|
||||||
VITE_PASSKEYS_ENABLED=true
|
VITE_PASSKEYS_ENABLED=true
|
||||||
@@ -4,12 +4,6 @@ module.exports = {
|
|||||||
node: true,
|
node: true,
|
||||||
es2022: true,
|
es2022: true,
|
||||||
},
|
},
|
||||||
ignorePatterns: [
|
|
||||||
'node_modules/',
|
|
||||||
'dist/',
|
|
||||||
'dist-electron/',
|
|
||||||
'*.d.ts'
|
|
||||||
],
|
|
||||||
extends: [
|
extends: [
|
||||||
"plugin:vue/vue3-recommended",
|
"plugin:vue/vue3-recommended",
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
|
|||||||
78
.gitignore
vendored
@@ -51,80 +51,6 @@ vendor/
|
|||||||
# Build logs
|
# Build logs
|
||||||
build_logs/
|
build_logs/
|
||||||
|
|
||||||
# PWA icon files generated by capacitor-assets
|
android/app/src/main/assets/public
|
||||||
icons
|
android/app/src/main/res
|
||||||
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Generated Android assets and resources (should be generated during build)
|
|
||||||
android/app/src/main/assets/public/
|
|
||||||
|
|
||||||
# Generated Android resources (icons, splash screens, etc.)
|
|
||||||
android/app/src/main/res/drawable*/
|
|
||||||
android/app/src/main/res/mipmap*/
|
|
||||||
android/app/src/main/res/values/ic_launcher_background.xml
|
|
||||||
|
|
||||||
# Keep these Android configuration files in version control:
|
|
||||||
# - android/app/src/main/assets/capacitor.plugins.json
|
|
||||||
# - android/app/src/main/res/values/strings.xml
|
|
||||||
# - android/app/src/main/res/values/styles.xml
|
|
||||||
# - android/app/src/main/res/layout/activity_main.xml
|
|
||||||
# - android/app/src/main/res/xml/config.xml
|
|
||||||
# - android/app/src/main/res/xml/file_paths.xml
|
|
||||||
|
|
||||||
sql-wasm.wasm
|
|
||||||
|
|
||||||
# Temporary and generated files
|
|
||||||
temp.*
|
|
||||||
*.tmp
|
|
||||||
*.temp
|
|
||||||
*.bak
|
|
||||||
*.cache
|
|
||||||
git.diff.*
|
|
||||||
*.har
|
|
||||||
|
|
||||||
# Development artifacts
|
|
||||||
dev-dist/
|
|
||||||
*.map
|
|
||||||
|
|
||||||
# OS generated files
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Capacitor build outputs and generated files
|
|
||||||
android/app/build/
|
|
||||||
android/capacitor-cordova-android-plugins/build/
|
|
||||||
ios/App/App/public/assets/
|
|
||||||
ios/App/App/build/
|
|
||||||
ios/App/build/
|
|
||||||
|
|
||||||
# Capacitor build artifacts (covered by android/app/build/ above)
|
|
||||||
|
|
||||||
# Keep these Capacitor files in version control:
|
|
||||||
# - capacitor.config.json (root, electron, ios)
|
|
||||||
# - src/main.capacitor.ts
|
|
||||||
# - vite.config.capacitor.mts
|
|
||||||
# - android/capacitor.settings.gradle
|
|
||||||
# - android/app/capacitor.build.gradle
|
|
||||||
# - android/app/src/main/assets/capacitor.plugins.json
|
|
||||||
|
|
||||||
# Electron build outputs and generated files
|
|
||||||
electron/build/
|
|
||||||
electron/app/
|
|
||||||
electron/dist/
|
|
||||||
electron/out/
|
|
||||||
|
|
||||||
# Keep these Electron files in version control:
|
|
||||||
# - electron/src/preload.ts (source)
|
|
||||||
# - electron/src/index.ts (source)
|
|
||||||
# - electron/src/setup.ts (source)
|
|
||||||
# - electron/package.json
|
|
||||||
# - electron/electron-builder.config.json
|
|
||||||
# - electron/build-packages.sh
|
|
||||||
# - electron/live-runner.js
|
|
||||||
# - electron/resources/electron-publisher-custom.js
|
|
||||||
|
|
||||||
# Gradle cache files
|
|
||||||
android/.gradle/file-system.probe
|
|
||||||
android/.gradle/caches/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"MD013": {"code_blocks": false}}
|
|
||||||
2001
BUILDING.md
40
CHANGELOG.md
@@ -5,46 +5,6 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [1.0.3] - 2025.07.12
|
|
||||||
### Changed
|
|
||||||
- Photo is pinned to profile mode
|
|
||||||
### Fixed
|
|
||||||
- Deep link URLs (and other prod settings)
|
|
||||||
- Error in BVC begin view
|
|
||||||
|
|
||||||
## [Unreleased]
|
|
||||||
### Changed
|
|
||||||
- Photo is pinned to profile mode
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.2] - 2025.06.20 - 276e0a741bc327de3380c4e508cccb7fee58c06d
|
|
||||||
### Added
|
|
||||||
- Version on feed title
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.1] - 2025.06.20
|
|
||||||
### Added
|
|
||||||
- Allow a user to block someone else's content from view
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0] - 2025.06.20 - 5aa693de6337e5dbb278bfddc6bd39094bc14f73
|
|
||||||
### Added
|
|
||||||
- Web-oriented migration from IndexedDB to SQLite
|
|
||||||
|
|
||||||
|
|
||||||
## [0.5.8]
|
|
||||||
### Added
|
|
||||||
- /deep-link/ path for URLs that are shared with people
|
|
||||||
### Changed
|
|
||||||
- External links now go to /deep-link/...
|
|
||||||
- Feed visuals now have arrow imagery from giver to receiver
|
|
||||||
|
|
||||||
|
|
||||||
## [0.4.7]
|
|
||||||
### Fixed
|
|
||||||
- Cameras everywhere
|
|
||||||
### Changed
|
|
||||||
- IndexedDB -> SQLite
|
|
||||||
|
|
||||||
|
|
||||||
## [0.4.5] - 2025.02.23
|
## [0.4.5] - 2025.02.23
|
||||||
|
|||||||
166
Dockerfile
@@ -1,170 +1,36 @@
|
|||||||
# TimeSafari Docker Build
|
# Build stage
|
||||||
# Author: Matthew Raymer
|
FROM node:22-alpine3.20 AS builder
|
||||||
# Description: Multi-stage Docker build for TimeSafari web application
|
|
||||||
#
|
|
||||||
# Build Process:
|
|
||||||
# 1. Base stage: Node.js with build dependencies
|
|
||||||
# 2. Builder stage: Copy pre-built web assets from host
|
|
||||||
# 3. Production stage: Nginx server with optimized assets
|
|
||||||
#
|
|
||||||
# Note: Web assets are built on the host using npm scripts before Docker build
|
|
||||||
#
|
|
||||||
# Security Features:
|
|
||||||
# - Non-root user execution
|
|
||||||
# - Minimal attack surface with Alpine Linux
|
|
||||||
# - Multi-stage build to reduce image size
|
|
||||||
# - No build dependencies in final image
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# IMPORTANT: Build web assets first, then build Docker image
|
|
||||||
#
|
|
||||||
# Using npm scripts (recommended):
|
|
||||||
# Production: npm run build:web:docker:prod
|
|
||||||
# Test: npm run build:web:docker:test
|
|
||||||
# Development: npm run build:web:docker
|
|
||||||
#
|
|
||||||
# Manual workflow:
|
|
||||||
# 1. Build web assets: npm run build:web:build -- --mode production
|
|
||||||
# 2. Build Docker: docker build -t timesafari:latest .
|
|
||||||
#
|
|
||||||
# Note: For development, use npm run build:web directly (no Docker needed)
|
|
||||||
#
|
|
||||||
# Build Arguments:
|
|
||||||
# BUILD_MODE: development, test, or production (default: production)
|
|
||||||
# NODE_ENV: node environment (default: production)
|
|
||||||
#
|
|
||||||
# Environment Variables:
|
|
||||||
# NODE_ENV: Build environment (development/production)
|
|
||||||
# BUILD_MODE: Build mode for asset selection (development/test/production)
|
|
||||||
#
|
|
||||||
# Build Context:
|
|
||||||
# This Dockerfile is designed to work when the build context is set to
|
|
||||||
# ./crowd-funder-for-time-pwa from the parent directory (where docker-compose.yml is located)
|
|
||||||
|
|
||||||
# =============================================================================
|
# Install build dependencies
|
||||||
# BASE STAGE - Common dependencies and setup
|
|
||||||
# =============================================================================
|
|
||||||
FROM node:22-alpine3.20 AS base
|
|
||||||
|
|
||||||
# Install system dependencies for build process
|
RUN apk add --no-cache bash git python3 py3-pip py3-setuptools make g++ gcc
|
||||||
RUN apk add --no-cache \
|
|
||||||
bash \
|
|
||||||
git \
|
|
||||||
python3 \
|
|
||||||
py3-pip \
|
|
||||||
py3-setuptools \
|
|
||||||
make \
|
|
||||||
g++ \
|
|
||||||
gcc \
|
|
||||||
&& rm -rf /var/cache/apk/*
|
|
||||||
|
|
||||||
# Create non-root user for security
|
|
||||||
RUN addgroup -g 1001 -S nodejs && \
|
|
||||||
adduser -S nextjs -u 1001
|
|
||||||
|
|
||||||
# Set working directory
|
# Set working directory
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy package files for dependency installation
|
# Copy package files
|
||||||
# Note: These files are in the project root (crowd-funder-for-time-pwa directory)
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
|
|
||||||
# Install dependencies with security audit
|
# Install dependencies
|
||||||
RUN npm ci --only=production --audit --fund=false && \
|
RUN npm ci
|
||||||
npm audit fix --audit-level=moderate || true
|
|
||||||
|
|
||||||
# =============================================================================
|
# Copy source code
|
||||||
# BUILDER STAGE - Copy pre-built assets
|
COPY . .
|
||||||
# =============================================================================
|
|
||||||
FROM base AS builder
|
|
||||||
|
|
||||||
# Define build arguments with defaults
|
# Build the application
|
||||||
ARG BUILD_MODE=production
|
RUN npm run build:web
|
||||||
ARG NODE_ENV=production
|
|
||||||
|
|
||||||
# Set environment variables from build arguments
|
# Production stage
|
||||||
ENV BUILD_MODE=${BUILD_MODE}
|
FROM nginx:alpine
|
||||||
ENV NODE_ENV=${NODE_ENV}
|
|
||||||
|
|
||||||
# Copy pre-built assets from host
|
|
||||||
# Note: dist/ directory is in the project root (crowd-funder-for-time-pwa directory)
|
|
||||||
COPY dist/ ./dist/
|
|
||||||
|
|
||||||
# Verify build output exists
|
|
||||||
RUN ls -la dist/ || (echo "Build output not found in dist/ directory" && exit 1)
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# PRODUCTION STAGE - Nginx server
|
|
||||||
# =============================================================================
|
|
||||||
FROM nginx:alpine AS production
|
|
||||||
|
|
||||||
# Define build arguments for production stage
|
|
||||||
ARG BUILD_MODE=production
|
|
||||||
ARG NODE_ENV=production
|
|
||||||
|
|
||||||
# Set environment variables
|
|
||||||
ENV BUILD_MODE=${BUILD_MODE}
|
|
||||||
ENV NODE_ENV=${NODE_ENV}
|
|
||||||
|
|
||||||
# Install security updates and clean cache
|
|
||||||
RUN apk update && \
|
|
||||||
apk upgrade && \
|
|
||||||
apk add --no-cache \
|
|
||||||
curl \
|
|
||||||
&& rm -rf /var/cache/apk/*
|
|
||||||
|
|
||||||
# Use existing nginx user from base image (nginx user and group already exist)
|
|
||||||
# No need to create new user as nginx:alpine already has nginx user
|
|
||||||
|
|
||||||
# Copy main nginx configuration
|
|
||||||
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
|
||||||
|
|
||||||
# Copy production nginx configuration
|
|
||||||
COPY docker/default.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
# Copy built assets from builder stage
|
# Copy built assets from builder stage
|
||||||
COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
# Create necessary directories with proper permissions
|
# Copy nginx configuration if needed
|
||||||
RUN mkdir -p /var/cache/nginx /var/log/nginx /tmp && \
|
# COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
chown -R nginx:nginx /var/cache/nginx /var/log/nginx /tmp && \
|
|
||||||
chown -R nginx:nginx /usr/share/nginx/html
|
|
||||||
|
|
||||||
# Switch to non-root user
|
|
||||||
USER nginx
|
|
||||||
|
|
||||||
# Expose port 80
|
# Expose port 80
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
# Health check
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
||||||
CMD curl -f http://localhost/ || exit 1
|
|
||||||
|
|
||||||
# Start nginx with proper signal handling
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# TEST STAGE - For test environment testing
|
|
||||||
# =============================================================================
|
|
||||||
FROM production AS test
|
|
||||||
|
|
||||||
# Define build arguments for test stage
|
|
||||||
ARG BUILD_MODE=test
|
|
||||||
ARG NODE_ENV=test
|
|
||||||
|
|
||||||
# Set environment variables
|
|
||||||
ENV BUILD_MODE=${BUILD_MODE}
|
|
||||||
ENV NODE_ENV=${NODE_ENV}
|
|
||||||
|
|
||||||
# Copy test-specific nginx configuration
|
|
||||||
COPY docker/staging.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
# Expose port 80
|
|
||||||
EXPOSE 80
|
|
||||||
|
|
||||||
# Health check for staging
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
||||||
CMD curl -f http://localhost/health || exit 1
|
|
||||||
|
|
||||||
# Start nginx
|
# Start nginx
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
1
Gemfile
@@ -1,4 +1,5 @@
|
|||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "fastlane"
|
||||||
gem "cocoapods"
|
gem "cocoapods"
|
||||||
|
|
||||||
|
|||||||
187
Gemfile.lock
@@ -22,7 +22,26 @@ GEM
|
|||||||
algoliasearch (1.27.5)
|
algoliasearch (1.27.5)
|
||||||
httpclient (~> 2.8, >= 2.8.3)
|
httpclient (~> 2.8, >= 2.8.3)
|
||||||
json (>= 1.5.1)
|
json (>= 1.5.1)
|
||||||
|
artifactory (3.0.17)
|
||||||
atomos (0.1.3)
|
atomos (0.1.3)
|
||||||
|
aws-eventstream (1.3.2)
|
||||||
|
aws-partitions (1.1066.0)
|
||||||
|
aws-sdk-core (3.220.1)
|
||||||
|
aws-eventstream (~> 1, >= 1.3.0)
|
||||||
|
aws-partitions (~> 1, >= 1.992.0)
|
||||||
|
aws-sigv4 (~> 1.9)
|
||||||
|
base64
|
||||||
|
jmespath (~> 1, >= 1.6.1)
|
||||||
|
aws-sdk-kms (1.99.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.216.0)
|
||||||
|
aws-sigv4 (~> 1.5)
|
||||||
|
aws-sdk-s3 (1.182.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.216.0)
|
||||||
|
aws-sdk-kms (~> 1)
|
||||||
|
aws-sigv4 (~> 1.5)
|
||||||
|
aws-sigv4 (1.11.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
babosa (1.0.4)
|
||||||
base64 (0.2.0)
|
base64 (0.2.0)
|
||||||
benchmark (0.4.0)
|
benchmark (0.4.0)
|
||||||
bigdecimal (3.1.9)
|
bigdecimal (3.1.9)
|
||||||
@@ -64,13 +83,96 @@ GEM
|
|||||||
nap (>= 0.8, < 2.0)
|
nap (>= 0.8, < 2.0)
|
||||||
netrc (~> 0.11)
|
netrc (~> 0.11)
|
||||||
cocoapods-try (1.2.0)
|
cocoapods-try (1.2.0)
|
||||||
|
colored (1.2)
|
||||||
colored2 (3.1.2)
|
colored2 (3.1.2)
|
||||||
|
commander (4.6.0)
|
||||||
|
highline (~> 2.0.0)
|
||||||
concurrent-ruby (1.3.5)
|
concurrent-ruby (1.3.5)
|
||||||
connection_pool (2.5.0)
|
connection_pool (2.5.0)
|
||||||
|
declarative (0.0.20)
|
||||||
|
digest-crc (0.7.0)
|
||||||
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
domain_name (0.6.20240107)
|
||||||
|
dotenv (2.8.1)
|
||||||
drb (2.2.1)
|
drb (2.2.1)
|
||||||
|
emoji_regex (3.2.3)
|
||||||
escape (0.0.4)
|
escape (0.0.4)
|
||||||
ethon (0.16.0)
|
ethon (0.16.0)
|
||||||
ffi (>= 1.15.0)
|
ffi (>= 1.15.0)
|
||||||
|
excon (0.112.0)
|
||||||
|
faraday (1.10.4)
|
||||||
|
faraday-em_http (~> 1.0)
|
||||||
|
faraday-em_synchrony (~> 1.0)
|
||||||
|
faraday-excon (~> 1.1)
|
||||||
|
faraday-httpclient (~> 1.0)
|
||||||
|
faraday-multipart (~> 1.0)
|
||||||
|
faraday-net_http (~> 1.0)
|
||||||
|
faraday-net_http_persistent (~> 1.0)
|
||||||
|
faraday-patron (~> 1.0)
|
||||||
|
faraday-rack (~> 1.0)
|
||||||
|
faraday-retry (~> 1.0)
|
||||||
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-cookie_jar (0.0.7)
|
||||||
|
faraday (>= 0.8.0)
|
||||||
|
http-cookie (~> 1.0.0)
|
||||||
|
faraday-em_http (1.0.0)
|
||||||
|
faraday-em_synchrony (1.0.0)
|
||||||
|
faraday-excon (1.1.0)
|
||||||
|
faraday-httpclient (1.0.1)
|
||||||
|
faraday-multipart (1.1.0)
|
||||||
|
multipart-post (~> 2.0)
|
||||||
|
faraday-net_http (1.0.2)
|
||||||
|
faraday-net_http_persistent (1.2.0)
|
||||||
|
faraday-patron (1.0.0)
|
||||||
|
faraday-rack (1.0.0)
|
||||||
|
faraday-retry (1.0.3)
|
||||||
|
faraday_middleware (1.2.1)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
fastimage (2.4.0)
|
||||||
|
fastlane (2.227.0)
|
||||||
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
|
addressable (>= 2.8, < 3.0.0)
|
||||||
|
artifactory (~> 3.0)
|
||||||
|
aws-sdk-s3 (~> 1.0)
|
||||||
|
babosa (>= 1.0.3, < 2.0.0)
|
||||||
|
bundler (>= 1.12.0, < 3.0.0)
|
||||||
|
colored (~> 1.2)
|
||||||
|
commander (~> 4.6)
|
||||||
|
dotenv (>= 2.1.1, < 3.0.0)
|
||||||
|
emoji_regex (>= 0.1, < 4.0)
|
||||||
|
excon (>= 0.71.0, < 1.0.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
faraday-cookie_jar (~> 0.0.6)
|
||||||
|
faraday_middleware (~> 1.0)
|
||||||
|
fastimage (>= 2.1.0, < 3.0.0)
|
||||||
|
fastlane-sirp (>= 1.0.0)
|
||||||
|
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||||
|
google-apis-androidpublisher_v3 (~> 0.3)
|
||||||
|
google-apis-playcustomapp_v1 (~> 0.1)
|
||||||
|
google-cloud-env (>= 1.6.0, < 2.0.0)
|
||||||
|
google-cloud-storage (~> 1.31)
|
||||||
|
highline (~> 2.0)
|
||||||
|
http-cookie (~> 1.0.5)
|
||||||
|
json (< 3.0.0)
|
||||||
|
jwt (>= 2.1.0, < 3)
|
||||||
|
mini_magick (>= 4.9.4, < 5.0.0)
|
||||||
|
multipart-post (>= 2.0.0, < 3.0.0)
|
||||||
|
naturally (~> 2.2)
|
||||||
|
optparse (>= 0.1.1, < 1.0.0)
|
||||||
|
plist (>= 3.1.0, < 4.0.0)
|
||||||
|
rubyzip (>= 2.0.0, < 3.0.0)
|
||||||
|
security (= 0.1.5)
|
||||||
|
simctl (~> 1.6.3)
|
||||||
|
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||||
|
terminal-table (~> 3)
|
||||||
|
tty-screen (>= 0.6.3, < 1.0.0)
|
||||||
|
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||||
|
word_wrap (~> 1.0.0)
|
||||||
|
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||||
|
xcpretty (~> 0.4.0)
|
||||||
|
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
|
||||||
|
fastlane-sirp (1.0.0)
|
||||||
|
sysrandom (~> 1.0)
|
||||||
ffi (1.17.1)
|
ffi (1.17.1)
|
||||||
ffi (1.17.1-aarch64-linux-gnu)
|
ffi (1.17.1-aarch64-linux-gnu)
|
||||||
ffi (1.17.1-aarch64-linux-musl)
|
ffi (1.17.1-aarch64-linux-musl)
|
||||||
@@ -85,27 +187,107 @@ GEM
|
|||||||
fourflusher (2.3.1)
|
fourflusher (2.3.1)
|
||||||
fuzzy_match (2.0.4)
|
fuzzy_match (2.0.4)
|
||||||
gh_inspector (1.1.3)
|
gh_inspector (1.1.3)
|
||||||
|
google-apis-androidpublisher_v3 (0.54.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-core (0.11.3)
|
||||||
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
representable (~> 3.0)
|
||||||
|
retriable (>= 2.0, < 4.a)
|
||||||
|
rexml
|
||||||
|
google-apis-iamcredentials_v1 (0.17.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-playcustomapp_v1 (0.13.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-storage_v1 (0.31.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-cloud-core (1.8.0)
|
||||||
|
google-cloud-env (>= 1.0, < 3.a)
|
||||||
|
google-cloud-errors (~> 1.0)
|
||||||
|
google-cloud-env (1.6.0)
|
||||||
|
faraday (>= 0.17.3, < 3.0)
|
||||||
|
google-cloud-errors (1.5.0)
|
||||||
|
google-cloud-storage (1.47.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
digest-crc (~> 0.4)
|
||||||
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
|
google-apis-storage_v1 (~> 0.31.0)
|
||||||
|
google-cloud-core (~> 1.6)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
googleauth (1.8.1)
|
||||||
|
faraday (>= 0.17.3, < 3.a)
|
||||||
|
jwt (>= 1.4, < 3.0)
|
||||||
|
multi_json (~> 1.11)
|
||||||
|
os (>= 0.9, < 2.0)
|
||||||
|
signet (>= 0.16, < 2.a)
|
||||||
|
highline (2.0.3)
|
||||||
|
http-cookie (1.0.8)
|
||||||
|
domain_name (~> 0.5)
|
||||||
httpclient (2.9.0)
|
httpclient (2.9.0)
|
||||||
mutex_m
|
mutex_m
|
||||||
i18n (1.14.7)
|
i18n (1.14.7)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
jmespath (1.6.2)
|
||||||
json (2.10.2)
|
json (2.10.2)
|
||||||
|
jwt (2.10.1)
|
||||||
|
base64
|
||||||
logger (1.6.6)
|
logger (1.6.6)
|
||||||
|
mini_magick (4.13.2)
|
||||||
|
mini_mime (1.1.5)
|
||||||
minitest (5.25.5)
|
minitest (5.25.5)
|
||||||
molinillo (0.8.0)
|
molinillo (0.8.0)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
multipart-post (2.4.1)
|
||||||
mutex_m (0.3.0)
|
mutex_m (0.3.0)
|
||||||
nanaimo (0.4.0)
|
nanaimo (0.4.0)
|
||||||
nap (1.1.0)
|
nap (1.1.0)
|
||||||
|
naturally (2.2.1)
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
nkf (0.2.0)
|
nkf (0.2.0)
|
||||||
|
optparse (0.6.0)
|
||||||
|
os (1.1.4)
|
||||||
|
plist (3.7.2)
|
||||||
public_suffix (4.0.7)
|
public_suffix (4.0.7)
|
||||||
|
rake (13.2.1)
|
||||||
|
representable (3.2.0)
|
||||||
|
declarative (< 0.1.0)
|
||||||
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
|
uber (< 0.2.0)
|
||||||
|
retriable (3.1.2)
|
||||||
rexml (3.4.1)
|
rexml (3.4.1)
|
||||||
|
rouge (3.28.0)
|
||||||
ruby-macho (2.5.1)
|
ruby-macho (2.5.1)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
rubyzip (2.4.1)
|
||||||
securerandom (0.4.1)
|
securerandom (0.4.1)
|
||||||
|
security (0.1.5)
|
||||||
|
signet (0.19.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
faraday (>= 0.17.5, < 3.a)
|
||||||
|
jwt (>= 1.5, < 3.0)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
simctl (1.6.10)
|
||||||
|
CFPropertyList
|
||||||
|
naturally
|
||||||
|
sysrandom (1.0.5)
|
||||||
|
terminal-notifier (2.0.0)
|
||||||
|
terminal-table (3.0.2)
|
||||||
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
|
trailblazer-option (0.1.2)
|
||||||
|
tty-cursor (0.7.1)
|
||||||
|
tty-screen (0.8.2)
|
||||||
|
tty-spinner (0.9.3)
|
||||||
|
tty-cursor (~> 0.7)
|
||||||
typhoeus (1.4.1)
|
typhoeus (1.4.1)
|
||||||
ethon (>= 0.9.0)
|
ethon (>= 0.9.0)
|
||||||
tzinfo (2.0.6)
|
tzinfo (2.0.6)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
uber (0.1.0)
|
||||||
|
unicode-display_width (2.6.0)
|
||||||
|
word_wrap (1.0.0)
|
||||||
xcodeproj (1.27.0)
|
xcodeproj (1.27.0)
|
||||||
CFPropertyList (>= 2.3.3, < 4.0)
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
atomos (~> 0.1.3)
|
atomos (~> 0.1.3)
|
||||||
@@ -113,6 +295,10 @@ GEM
|
|||||||
colored2 (~> 3.1)
|
colored2 (~> 3.1)
|
||||||
nanaimo (~> 0.4.0)
|
nanaimo (~> 0.4.0)
|
||||||
rexml (>= 3.3.6, < 4.0)
|
rexml (>= 3.3.6, < 4.0)
|
||||||
|
xcpretty (0.4.0)
|
||||||
|
rouge (~> 3.28.0)
|
||||||
|
xcpretty-travis-formatter (1.0.1)
|
||||||
|
xcpretty (~> 0.2, >= 0.0.7)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
aarch64-linux-gnu
|
aarch64-linux-gnu
|
||||||
@@ -129,6 +315,7 @@ PLATFORMS
|
|||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
cocoapods
|
cocoapods
|
||||||
|
fastlane
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.6.5
|
2.6.5
|
||||||
|
|||||||
127
README.md
@@ -3,32 +3,6 @@
|
|||||||
[Time Safari](https://timesafari.org/) allows people to ease into collaboration: start with expressions of gratitude
|
[Time Safari](https://timesafari.org/) allows people to ease into collaboration: start with expressions of gratitude
|
||||||
and expand to crowd-fund with time & money, then record and see the impact of contributions.
|
and expand to crowd-fund with time & money, then record and see the impact of contributions.
|
||||||
|
|
||||||
## Database Migration Status
|
|
||||||
|
|
||||||
**Current Status**: The application is undergoing a migration from Dexie (IndexedDB) to SQLite using absurd-sql. This migration is in **Phase 2** with a well-defined migration fence in place.
|
|
||||||
|
|
||||||
### Migration Progress
|
|
||||||
- ✅ **SQLite Database Service**: Fully implemented with absurd-sql
|
|
||||||
- ✅ **Platform Service Layer**: Unified database interface across platforms
|
|
||||||
- ✅ **Settings Migration**: Core user settings transferred
|
|
||||||
- ✅ **Account Migration**: Identity and key management
|
|
||||||
- 🔄 **Contact Migration**: User contact data (via import interface)
|
|
||||||
- 📋 **Code Cleanup**: Remove unused Dexie imports
|
|
||||||
|
|
||||||
### Migration Fence
|
|
||||||
The migration is controlled by a **migration fence** that separates legacy Dexie code from the new SQLite implementation. See [Migration Fence Definition](doc/migration-fence-definition.md) for complete details.
|
|
||||||
|
|
||||||
**Key Points**:
|
|
||||||
- Legacy Dexie database is disabled by default
|
|
||||||
- All database operations go through `PlatformServiceMixin`
|
|
||||||
- Migration tools provide controlled access to both databases
|
|
||||||
- Clear separation between legacy and new code
|
|
||||||
|
|
||||||
### Migration Documentation
|
|
||||||
- [Migration Guide](doc/migration-to-wa-sqlite.md) - Complete migration process
|
|
||||||
- [Migration Fence Definition](doc/migration-fence-definition.md) - Fence boundaries and rules
|
|
||||||
- [Database Migration Guide](doc/database-migration-guide.md) - User-facing migration tools
|
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
See [project.task.yaml](project.task.yaml) for current priorities.
|
See [project.task.yaml](project.task.yaml) for current priorities.
|
||||||
@@ -45,92 +19,18 @@ npm install
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
See [BUILDING.md](BUILDING.md) for comprehensive build instructions for all platforms (Web, Electron, iOS, Android, Docker).
|
See [BUILDING.md](BUILDING.md) for more details.
|
||||||
|
|
||||||
## Development Database Clearing
|
|
||||||
|
|
||||||
TimeSafari provides a simple script-based approach to clear the database for development purposes.
|
|
||||||
|
|
||||||
### Quick Usage
|
|
||||||
```bash
|
|
||||||
# Run the database clearing script
|
|
||||||
./scripts/clear-database.sh
|
|
||||||
|
|
||||||
# Then restart your development server
|
|
||||||
npm run build:electron:dev # For Electron
|
|
||||||
npm run build:web:dev # For Web
|
|
||||||
```
|
|
||||||
|
|
||||||
### What It Does
|
|
||||||
|
|
||||||
#### **Electron (Desktop App)**
|
|
||||||
- Automatically finds and clears the SQLite database files
|
|
||||||
- Works on Linux, macOS, and Windows
|
|
||||||
- Clears all data and forces fresh migrations on next startup
|
|
||||||
|
|
||||||
#### **Web Browser**
|
|
||||||
- Provides instructions for using custom browser data directories
|
|
||||||
- Shows manual clearing via browser DevTools
|
|
||||||
- Ensures reliable database clearing without browser complications
|
|
||||||
|
|
||||||
### Safety Features
|
|
||||||
- ✅ **Interactive Script**: Guides you through the process
|
|
||||||
- ✅ **Platform Detection**: Automatically detects your OS
|
|
||||||
- ✅ **Clear Instructions**: Step-by-step guidance for each platform
|
|
||||||
- ✅ **Safe Paths**: Only clears TimeSafari-specific data
|
|
||||||
|
|
||||||
### Manual Commands (if needed)
|
|
||||||
|
|
||||||
#### **Electron Database Location**
|
|
||||||
```bash
|
|
||||||
# Linux
|
|
||||||
rm -rf ~/.config/TimeSafari/*
|
|
||||||
|
|
||||||
# macOS
|
|
||||||
rm -rf ~/Library/Application\ Support/TimeSafari/*
|
|
||||||
|
|
||||||
# Windows
|
|
||||||
rmdir /s /q %APPDATA%\TimeSafari
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Web Browser (Custom Data Directory)**
|
|
||||||
```bash
|
|
||||||
# Create isolated browser profile
|
|
||||||
mkdir ~/timesafari-dev-data
|
|
||||||
```
|
|
||||||
|
|
||||||
## Domain Configuration
|
|
||||||
|
|
||||||
TimeSafari uses a centralized domain configuration system to ensure consistent
|
|
||||||
URL generation across all environments. This prevents localhost URLs from
|
|
||||||
appearing in shared links during development.
|
|
||||||
|
|
||||||
### Key Features
|
|
||||||
- ✅ **Production URLs for Sharing**: All copy link buttons use production domain
|
|
||||||
- ✅ **Environment-Specific Internal URLs**: Internal operations use appropriate
|
|
||||||
environment URLs
|
|
||||||
- ✅ **Single Point of Control**: Change domain in one place for entire app
|
|
||||||
- ✅ **Type-Safe Configuration**: Full TypeScript support
|
|
||||||
|
|
||||||
### Quick Reference
|
|
||||||
```typescript
|
|
||||||
// For sharing functionality (always production)
|
|
||||||
import { PROD_SHARE_DOMAIN } from "@/constants/app";
|
|
||||||
const shareLink = `${PROD_SHARE_DOMAIN}/deep-link/claim/123`;
|
|
||||||
|
|
||||||
// For internal operations (environment-specific)
|
|
||||||
import { APP_SERVER } from "@/constants/app";
|
|
||||||
const apiUrl = `${APP_SERVER}/api/claim/123`;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- [Domain Configuration System](docs/domain-configuration.md) - Complete guide
|
|
||||||
- [Constants and Configuration](src/constants/app.ts) - Core constants
|
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
See [TESTING.md](test-playwright/TESTING.md) for detailed test instructions.
|
See [TESTING.md](test-playwright/TESTING.md) for detailed test instructions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Icons
|
## Icons
|
||||||
|
|
||||||
Application icons are in the `assets` directory, processed by the `capacitor-assets` command.
|
Application icons are in the `assets` directory, processed by the `capacitor-assets` command.
|
||||||
@@ -166,25 +66,6 @@ Key principles:
|
|||||||
- Common interfaces are shared through `common.ts`
|
- Common interfaces are shared through `common.ts`
|
||||||
- Type definitions are generated from Zod schemas where possible
|
- Type definitions are generated from Zod schemas where possible
|
||||||
|
|
||||||
### Database Architecture
|
|
||||||
|
|
||||||
The application uses a platform-agnostic database layer with Vue mixins for service access:
|
|
||||||
|
|
||||||
* `src/services/PlatformService.ts` - Database interface definition
|
|
||||||
* `src/services/PlatformServiceFactory.ts` - Platform-specific service factory
|
|
||||||
* `src/services/AbsurdSqlDatabaseService.ts` - SQLite implementation
|
|
||||||
* `src/utils/PlatformServiceMixin.ts` - Vue mixin for database access with caching
|
|
||||||
* `src/db/` - Legacy Dexie database (migration in progress)
|
|
||||||
|
|
||||||
**Development Guidelines**:
|
|
||||||
|
|
||||||
- Always use `PlatformServiceMixin` for database operations in components
|
|
||||||
- Test with PlatformServiceMixin for new features
|
|
||||||
- Use migration tools for data transfer between systems
|
|
||||||
- Leverage mixin's ultra-concise methods: `$db()`, `$exec()`, `$one()`, `$contacts()`, `$settings()`
|
|
||||||
|
|
||||||
**Architecture Decision**: The project uses Vue mixins over Composition API composables for platform service access. See [Architecture Decisions](doc/architecture-decisions.md) for detailed rationale.
|
|
||||||
|
|
||||||
### Kudos
|
### Kudos
|
||||||
|
|
||||||
Gifts make the world go 'round!
|
Gifts make the world go 'round!
|
||||||
|
|||||||
7
android/.gitignore
vendored
@@ -84,6 +84,13 @@ freeline.py
|
|||||||
freeline/
|
freeline/
|
||||||
freeline_project_description.json
|
freeline_project_description.json
|
||||||
|
|
||||||
|
# fastlane
|
||||||
|
fastlane/report.xml
|
||||||
|
fastlane/Preview.html
|
||||||
|
fastlane/screenshots
|
||||||
|
fastlane/test_output
|
||||||
|
fastlane/readme.md
|
||||||
|
|
||||||
# Version control
|
# Version control
|
||||||
vcs.xml
|
vcs.xml
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ android {
|
|||||||
applicationId "app.timesafari.app"
|
applicationId "app.timesafari.app"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 35
|
versionCode 18
|
||||||
versionName "1.0.2"
|
versionName "0.4.7"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
aaptOptions {
|
aaptOptions {
|
||||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||||
@@ -91,8 +91,6 @@ dependencies {
|
|||||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||||
implementation project(':capacitor-android')
|
implementation project(':capacitor-android')
|
||||||
implementation project(':capacitor-community-sqlite')
|
|
||||||
implementation "androidx.biometric:biometric:1.2.0-alpha05"
|
|
||||||
testImplementation "junit:junit:$junitVersion"
|
testImplementation "junit:junit:$junitVersion"
|
||||||
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
||||||
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ android {
|
|||||||
|
|
||||||
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':capacitor-community-sqlite')
|
|
||||||
implementation project(':capacitor-mlkit-barcode-scanning')
|
implementation project(':capacitor-mlkit-barcode-scanning')
|
||||||
implementation project(':capacitor-app')
|
implementation project(':capacitor-app')
|
||||||
implementation project(':capacitor-camera')
|
implementation project(':capacitor-camera')
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/title_activity_main"
|
android:label="@string/title_activity_main"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:theme="@style/AppTheme.NoActionBarLaunch">
|
android:theme="@style/AppTheme.NoActionBarLaunch">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"appId": "app.timesafari",
|
"appId": "app.timesafari",
|
||||||
"appName": "TimeSafari",
|
"appName": "TimeSafari",
|
||||||
"webDir": "dist",
|
"webDir": "dist",
|
||||||
|
"bundledWebRuntime": false,
|
||||||
"server": {
|
"server": {
|
||||||
"cleartext": true
|
"cleartext": true
|
||||||
},
|
},
|
||||||
@@ -15,106 +16,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"SplashScreen": {
|
|
||||||
"launchShowDuration": 3000,
|
|
||||||
"launchAutoHide": true,
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"androidSplashResourceName": "splash",
|
|
||||||
"androidScaleType": "CENTER_CROP",
|
|
||||||
"showSpinner": false,
|
|
||||||
"androidSpinnerStyle": "large",
|
|
||||||
"iosSpinnerStyle": "small",
|
|
||||||
"spinnerColor": "#999999",
|
|
||||||
"splashFullScreen": true,
|
|
||||||
"splashImmersive": true
|
|
||||||
},
|
|
||||||
"CapacitorSQLite": {
|
|
||||||
"iosDatabaseLocation": "Library/CapacitorDatabase",
|
|
||||||
"iosIsEncryption": false,
|
|
||||||
"iosBiometric": {
|
|
||||||
"biometricAuth": false,
|
|
||||||
"biometricTitle": "Biometric login for TimeSafari"
|
|
||||||
},
|
|
||||||
"androidIsEncryption": false,
|
|
||||||
"androidBiometric": {
|
|
||||||
"biometricAuth": false,
|
|
||||||
"biometricTitle": "Biometric login for TimeSafari"
|
|
||||||
},
|
|
||||||
"electronIsEncryption": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ios": {
|
|
||||||
"contentInset": "never",
|
|
||||||
"allowsLinkPreview": true,
|
|
||||||
"scrollEnabled": true,
|
|
||||||
"limitsNavigationsToAppBoundDomains": true,
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"allowNavigation": [
|
|
||||||
"*.timesafari.app",
|
|
||||||
"*.jsdelivr.net",
|
|
||||||
"api.endorser.ch"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"android": {
|
|
||||||
"allowMixedContent": false,
|
|
||||||
"captureInput": true,
|
|
||||||
"webContentsDebuggingEnabled": false,
|
|
||||||
"allowNavigation": [
|
|
||||||
"*.timesafari.app",
|
|
||||||
"*.jsdelivr.net",
|
|
||||||
"api.endorser.ch"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"electron": {
|
|
||||||
"deepLinking": {
|
|
||||||
"schemes": [
|
|
||||||
"timesafari"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"buildOptions": {
|
|
||||||
"appId": "app.timesafari",
|
|
||||||
"productName": "TimeSafari",
|
|
||||||
"directories": {
|
|
||||||
"output": "dist-electron-packages"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist/**/*",
|
|
||||||
"electron/**/*"
|
|
||||||
],
|
|
||||||
"mac": {
|
|
||||||
"category": "public.app-category.productivity",
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "dmg",
|
|
||||||
"arch": [
|
|
||||||
"x64",
|
|
||||||
"arm64"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"win": {
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "nsis",
|
|
||||||
"arch": [
|
|
||||||
"x64"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "AppImage",
|
|
||||||
"arch": [
|
|
||||||
"x64"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"category": "Utility"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
[
|
[
|
||||||
{
|
|
||||||
"pkg": "@capacitor-community/sqlite",
|
|
||||||
"classpath": "com.getcapacitor.community.database.sqlite.CapacitorSQLitePlugin"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"pkg": "@capacitor-mlkit/barcode-scanning",
|
"pkg": "@capacitor-mlkit/barcode-scanning",
|
||||||
"classpath": "io.capawesome.capacitorjs.plugins.mlkit.barcodescanning.BarcodeScannerPlugin"
|
"classpath": "io.capawesome.capacitorjs.plugins.mlkit.barcodescanning.BarcodeScannerPlugin"
|
||||||
|
|||||||
0
android/app/src/main/assets/public/cordova.js
vendored
Normal file
0
android/app/src/main/assets/public/cordova_plugins.js
vendored
Normal file
BIN
android/app/src/main/assets/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 270 KiB |
|
After Width: | Height: | Size: 332 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 463 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 70 KiB |
BIN
android/app/src/main/assets/public/img/icons/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
android/app/src/main/assets/public/img/icons/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 46 KiB |
BIN
android/app/src/main/assets/public/img/icons/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
@@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
|
||||||
|
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M2480 4005 c-25 -7 -58 -20 -75 -29 -16 -9 -40 -16 -52 -16 -17 0
|
||||||
|
-24 -7 -28 -27 -3 -16 -14 -45 -24 -65 -21 -41 -13 -55 18 -38 25 13 67 13 92
|
||||||
|
-1 15 -8 35 -4 87 17 99 39 130 41 197 10 64 -29 77 -31 107 -15 20 11 20 11
|
||||||
|
-3 35 -12 13 -30 24 -38 24 -24 1 -132 38 -148 51 -8 7 -11 20 -7 32 12 37
|
||||||
|
-40 47 -126 22z"/>
|
||||||
|
<path d="M1450 3775 c-7 -8 -18 -15 -24 -15 -7 0 -31 -14 -54 -32 -29 -22 -38
|
||||||
|
-34 -29 -40 17 -11 77 -10 77 1 0 5 16 16 35 25 60 29 220 19 290 -18 17 -9
|
||||||
|
33 -16 37 -16 4 0 31 -15 60 -34 108 -70 224 -215 282 -353 30 -71 53 -190 42
|
||||||
|
-218 -10 -27 -23 -8 -52 75 -30 90 -88 188 -120 202 -13 6 -26 9 -29 6 -3 -2
|
||||||
|
11 -51 30 -108 28 -83 35 -119 35 -179 0 -120 -22 -127 -54 -17 -11 37 -13 21
|
||||||
|
-18 -154 -5 -180 -8 -200 -32 -264 -51 -132 -129 -245 -199 -288 -21 -12 -79
|
||||||
|
-49 -129 -80 -161 -102 -294 -141 -473 -141 -228 0 -384 76 -535 259 -81 99
|
||||||
|
-118 174 -154 312 -31 121 -35 273 -11 437 19 127 19 125 -4 125 -23 0 -51
|
||||||
|
-34 -87 -104 -14 -28 -33 -64 -41 -81 -19 -34 -22 -253 -7 -445 9 -106 12
|
||||||
|
-119 44 -170 19 -30 42 -67 50 -81 64 -113 85 -140 130 -169 28 -18 53 -44 61
|
||||||
|
-62 8 -20 36 -45 83 -76 62 -39 80 -46 151 -54 44 -5 96 -13 115 -18 78 -20
|
||||||
|
238 -31 282 -19 24 6 66 8 95 5 76 -9 169 24 319 114 32 19 80 56 106 82 27
|
||||||
|
26 52 48 58 48 5 0 27 26 50 58 48 66 56 70 132 71 62 1 165 29 238 64 112 55
|
||||||
|
177 121 239 245 37 76 39 113 10 267 -12 61 -23 131 -26 156 -5 46 -5 47 46
|
||||||
|
87 92 73 182 70 263 -8 l51 -49 -6 -61 c-4 -34 -13 -85 -21 -113 -28 -103 -30
|
||||||
|
-161 -4 -228 16 -44 32 -67 55 -83 18 -11 39 -37 47 -58 10 -23 37 -53 73 -81
|
||||||
|
32 -25 69 -57 82 -71 14 -14 34 -26 47 -26 12 0 37 -7 56 -15 20 -8 66 -17
|
||||||
|
104 -20 107 -10 110 -11 150 -71 50 -75 157 -177 197 -187 18 -5 53 -24 78
|
||||||
|
-42 71 -51 176 -82 304 -89 61 -4 127 -12 147 -18 29 -9 45 -8 77 6 23 9 50
|
||||||
|
16 60 16 31 0 163 46 216 76 28 15 75 46 105 69 30 23 69 49 85 58 17 8 46 31
|
||||||
|
64 51 19 20 40 36 47 36 18 0 77 70 100 120 32 66 45 108 55 173 5 32 16 71
|
||||||
|
24 87 43 84 43 376 0 549 -27 105 -43 127 -135 188 -30 21 -65 46 -77 57 -13
|
||||||
|
11 -23 17 -23 14 0 -3 21 -46 47 -94 79 -151 85 -166 115 -263 25 -83 28 -110
|
||||||
|
28 -226 0 -144 -17 -221 -75 -335 -39 -77 -208 -244 -304 -299 -451 -263 -975
|
||||||
|
-67 -1138 426 -23 70 -26 95 -28 254 -1 108 -7 183 -14 196 -6 12 -11 31 -11
|
||||||
|
43 0 32 31 122 52 149 10 13 18 28 18 34 0 5 25 40 56 78 60 73 172 170 219
|
||||||
|
190 30 12 30 13 6 17 -15 2 -29 -2 -37 -12 -6 -9 -16 -16 -22 -16 -6 0 -23
|
||||||
|
-11 -39 -24 -15 -12 -33 -25 -40 -27 -17 -6 -82 -60 -117 -97 -65 -70 -75 -82
|
||||||
|
-107 -133 -23 -34 -35 -46 -37 -35 -3 16 20 87 44 134 6 12 9 34 6 48 -4 22
|
||||||
|
-8 25 -31 19 -14 -3 -38 -15 -53 -26 -34 -24 -34 -21 -6 28 65 112 184 206
|
||||||
|
291 227 15 3 39 9 55 12 l27 6 -24 9 c-90 35 -304 -66 -478 -225 -39 -36 -74
|
||||||
|
-66 -77 -66 -22 0 18 82 72 148 19 23 32 46 28 49 -4 4 -26 13 -49 19 -73 21
|
||||||
|
-161 54 -171 64 -6 6 -20 10 -32 10 -21 0 -21 -1 -8 -40 45 -130 8 -247 -93
|
||||||
|
-299 -25 -13 -31 0 -14 29 15 22 1 33 -22 17 -56 -36 -117 -22 -117 28 0 13
|
||||||
|
-16 47 -35 76 -22 34 -33 60 -29 73 4 16 -3 26 -26 39 -16 10 -30 21 -30 25 1
|
||||||
|
18 54 64 87 76 l38 13 -33 5 c-30 4 -115 -18 -154 -42 -13 -7 -20 -5 -27 8 -9
|
||||||
|
16 -12 16 -53 1 -160 -61 -258 -104 -258 -114 0 -7 10 -20 21 -31 103 -91 217
|
||||||
|
-297 249 -449 28 -135 41 -237 35 -276 -14 -91 -48 -170 -97 -220 -44 -47 -68
|
||||||
|
-60 -68 -40 0 6 4 12 8 15 5 3 24 35 42 72 l33 67 -6 141 c-4 103 -11 158 -26
|
||||||
|
205 -12 35 -21 70 -21 77 0 7 -20 56 -45 108 -82 173 -227 322 -392 401 -67
|
||||||
|
33 -90 39 -163 42 -108 5 -130 10 -130 28 0 20 -63 20 -80 0z"/>
|
||||||
|
<path d="M3710 3765 c0 -20 8 -28 39 -41 22 -8 42 -22 45 -30 5 -14 42 -19 70
|
||||||
|
-8 10 4 -7 21 -58 55 -41 27 -79 49 -85 49 -6 0 -11 -11 -11 -25z"/>
|
||||||
|
<path d="M3173 3734 c-9 -25 10 -36 35 -18 12 8 22 19 22 25 0 16 -50 10 -57
|
||||||
|
-7z"/>
|
||||||
|
<path d="M1982 3728 c6 -16 36 -34 44 -26 3 4 4 14 1 23 -7 17 -51 21 -45 3z"/>
|
||||||
|
<path d="M1540 3620 c0 -5 7 -10 16 -10 8 0 12 5 9 10 -3 6 -10 10 -16 10 -5
|
||||||
|
0 -9 -4 -9 -10z"/>
|
||||||
|
<path d="M4467 3624 c-4 -4 23 -27 60 -50 84 -56 99 -58 67 -9 -28 43 -107 79
|
||||||
|
-127 59z"/>
|
||||||
|
<path d="M655 3552 c-11 -2 -26 -9 -33 -14 -7 -6 -27 -18 -45 -27 -36 -18 -58
|
||||||
|
-64 -39 -83 9 -9 25 1 70 43 53 48 78 78 70 84 -2 1 -12 -1 -23 -3z"/>
|
||||||
|
<path d="M1015 3460 c-112 -24 -247 -98 -303 -165 -53 -65 -118 -214 -136
|
||||||
|
-311 -20 -113 -20 -145 -1 -231 20 -88 49 -153 102 -230 79 -113 186 -182 331
|
||||||
|
-214 108 -24 141 -24 247 1 130 30 202 72 316 181 102 100 153 227 152 384 0
|
||||||
|
142 -58 293 -150 395 -60 67 -180 145 -261 171 -75 23 -232 34 -297 19z m340
|
||||||
|
-214 c91 -43 174 -154 175 -234 0 -18 -9 -51 -21 -73 -19 -37 -19 -42 -5 -64
|
||||||
|
35 -54 12 -121 -48 -142 -22 -7 -47 -19 -55 -27 -9 -8 -41 -27 -71 -42 -50
|
||||||
|
-26 -64 -29 -155 -29 -111 0 -152 14 -206 68 -49 49 -63 85 -64 162 0 59 4 78
|
||||||
|
28 118 31 52 96 105 141 114 23 5 33 17 56 68 46 103 121 130 225 81z"/>
|
||||||
|
<path d="M3985 3464 c-44 -7 -154 -44 -200 -67 -55 -28 -138 -96 -162 -132
|
||||||
|
-10 -16 -39 -75 -64 -130 l-44 -100 0 -160 0 -160 45 -90 c53 -108 152 -214
|
||||||
|
245 -264 59 -31 215 -71 281 -71 53 0 206 40 255 67 98 53 203 161 247 253 53
|
||||||
|
113 74 193 74 280 -1 304 -253 564 -557 575 -49 2 -103 1 -120 -1z m311 -220
|
||||||
|
c129 -68 202 -209 160 -309 -15 -35 -15 -42 -1 -72 26 -55 -3 -118 -59 -129
|
||||||
|
-19 -3 -43 -15 -53 -26 -26 -29 -99 -64 -165 -78 -45 -10 -69 -10 -120 -1 -74
|
||||||
|
15 -113 37 -161 91 -110 120 -50 331 109 385 24 8 44 23 52 39 6 14 18 38 25
|
||||||
|
53 33 72 127 93 213 47z"/>
|
||||||
|
<path d="M487 3394 c-21 -12 -27 -21 -25 -40 2 -14 7 -26 12 -27 14 -3 48 48
|
||||||
|
44 66 -3 14 -6 14 -31 1z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 705 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
Model Information:
|
||||||
|
* title: Lupine Plant
|
||||||
|
* source: https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439
|
||||||
|
* author: rufusrockwell (https://sketchfab.com/rufusrockwell)
|
||||||
|
|
||||||
|
Model License:
|
||||||
|
* license type: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
|
||||||
|
* requirements: Author must be credited. Commercial use is allowed.
|
||||||
|
|
||||||
|
If you use this 3D model in your project be sure to copy paste this credit wherever you share it:
|
||||||
|
This work is based on "Lupine Plant" (https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439) by rufusrockwell (https://sketchfab.com/rufusrockwell) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
|
||||||
BIN
android/app/src/main/assets/public/models/lupine_plant/scene.bin
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
{
|
||||||
|
"accessors": [
|
||||||
|
{
|
||||||
|
"bufferView": 2,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 2759,
|
||||||
|
"max": [
|
||||||
|
41.3074951171875,
|
||||||
|
40.37548828125,
|
||||||
|
87.85917663574219
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-35.245540618896484,
|
||||||
|
-36.895416259765625,
|
||||||
|
-0.9094290137290955
|
||||||
|
],
|
||||||
|
"type": "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 2,
|
||||||
|
"byteOffset": 33108,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 2759,
|
||||||
|
"max": [
|
||||||
|
0.9999382495880127,
|
||||||
|
0.9986748695373535,
|
||||||
|
0.9985831379890442
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-0.9998949766159058,
|
||||||
|
-0.9975876212120056,
|
||||||
|
-0.411094069480896
|
||||||
|
],
|
||||||
|
"type": "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 3,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 2759,
|
||||||
|
"max": [
|
||||||
|
0.9987699389457703,
|
||||||
|
0.9998998045921326,
|
||||||
|
0.9577858448028564,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-0.9987726807594299,
|
||||||
|
-0.9990445971488953,
|
||||||
|
-0.999801516532898,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"type": "VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 1,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 2759,
|
||||||
|
"max": [
|
||||||
|
1.0061479806900024,
|
||||||
|
0.9993550181388855
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
0.00279300007969141,
|
||||||
|
0.0011620000004768372
|
||||||
|
],
|
||||||
|
"type": "VEC2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 0,
|
||||||
|
"componentType": 5125,
|
||||||
|
"count": 6378,
|
||||||
|
"type": "SCALAR"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asset": {
|
||||||
|
"extras": {
|
||||||
|
"author": "rufusrockwell (https://sketchfab.com/rufusrockwell)",
|
||||||
|
"license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)",
|
||||||
|
"source": "https://sketchfab.com/3d-models/lupine-plant-bf30f1110c174d4baedda0ed63778439",
|
||||||
|
"title": "Lupine Plant"
|
||||||
|
},
|
||||||
|
"generator": "Sketchfab-12.68.0",
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"bufferViews": [
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 25512,
|
||||||
|
"name": "floatBufferViews",
|
||||||
|
"target": 34963
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 22072,
|
||||||
|
"byteOffset": 25512,
|
||||||
|
"byteStride": 8,
|
||||||
|
"name": "floatBufferViews",
|
||||||
|
"target": 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 66216,
|
||||||
|
"byteOffset": 47584,
|
||||||
|
"byteStride": 12,
|
||||||
|
"name": "floatBufferViews",
|
||||||
|
"target": 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 44144,
|
||||||
|
"byteOffset": 113800,
|
||||||
|
"byteStride": 16,
|
||||||
|
"name": "floatBufferViews",
|
||||||
|
"target": 34962
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"byteLength": 157944,
|
||||||
|
"uri": "scene.bin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"uri": "textures/lambert2SG_baseColor.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "textures/lambert2SG_normal.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials": [
|
||||||
|
{
|
||||||
|
"alphaCutoff": 0.2,
|
||||||
|
"alphaMode": "MASK",
|
||||||
|
"doubleSided": true,
|
||||||
|
"name": "lambert2SG",
|
||||||
|
"normalTexture": {
|
||||||
|
"index": 1
|
||||||
|
},
|
||||||
|
"pbrMetallicRoughness": {
|
||||||
|
"baseColorTexture": {
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
"metallicFactor": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes": [
|
||||||
|
{
|
||||||
|
"name": "Object_0",
|
||||||
|
"primitives": [
|
||||||
|
{
|
||||||
|
"attributes": {
|
||||||
|
"NORMAL": 1,
|
||||||
|
"POSITION": 0,
|
||||||
|
"TANGENT": 2,
|
||||||
|
"TEXCOORD_0": 3
|
||||||
|
},
|
||||||
|
"indices": 4,
|
||||||
|
"material": 0,
|
||||||
|
"mode": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"children": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"matrix": [
|
||||||
|
1.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
2.220446049250313e-16,
|
||||||
|
-1.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
2.220446049250313e-16,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"name": "Sketchfab_model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"children": [
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"name": "LupineSF.obj.cleaner.materialmerger.gles"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mesh": 0,
|
||||||
|
"name": "Object_2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"samplers": [
|
||||||
|
{
|
||||||
|
"magFilter": 9729,
|
||||||
|
"minFilter": 9987,
|
||||||
|
"wrapS": 10497,
|
||||||
|
"wrapT": 10497
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
"name": "Sketchfab_Scene",
|
||||||
|
"nodes": [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"sampler": 0,
|
||||||
|
"source": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sampler": 0,
|
||||||
|
"source": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 4.7 MiB |
2
android/app/src/main/assets/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
@@ -1,15 +1,7 @@
|
|||||||
package app.timesafari;
|
package app.timesafari;
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import com.getcapacitor.BridgeActivity;
|
import com.getcapacitor.BridgeActivity;
|
||||||
//import com.getcapacitor.community.sqlite.SQLite;
|
|
||||||
|
|
||||||
public class MainActivity extends BridgeActivity {
|
public class MainActivity extends BridgeActivity {
|
||||||
@Override
|
// ... existing code ...
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// Initialize SQLite
|
|
||||||
//registerPlugin(SQLite.class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package timesafari.app;
|
||||||
|
|
||||||
|
import com.getcapacitor.BridgeActivity;
|
||||||
|
|
||||||
|
public class MainActivity extends BridgeActivity {}
|
||||||
BIN
android/app/src/main/res/drawable-land-hdpi/splash.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
android/app/src/main/res/drawable-land-mdpi/splash.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
android/app/src/main/res/drawable-land-xhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
android/app/src/main/res/drawable-land-xxhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
android/app/src/main/res/drawable-land-xxxhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
android/app/src/main/res/drawable-port-hdpi/splash.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
android/app/src/main/res/drawable-port-mdpi/splash.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
android/app/src/main/res/drawable-port-xhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
android/app/src/main/res/drawable-port-xxhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
android/app/src/main/res/drawable-port-xxxhdpi/splash.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1" />
|
||||||
|
</vector>
|
||||||
170
android/app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#26A69A"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
</vector>
|
||||||
BIN
android/app/src/main/res/drawable/splash.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 15 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#FFFFFF</color>
|
||||||
|
</resources>
|
||||||
@@ -7,7 +7,7 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.11.1'
|
classpath 'com.android.tools.build:gradle:8.9.1'
|
||||||
classpath 'com.google.gms:google-services:4.4.0'
|
classpath 'com.google.gms:google-services:4.4.0'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
include ':capacitor-android'
|
include ':capacitor-android'
|
||||||
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
|
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
|
||||||
|
|
||||||
include ':capacitor-community-sqlite'
|
|
||||||
project(':capacitor-community-sqlite').projectDir = new File('../node_modules/@capacitor-community/sqlite/android')
|
|
||||||
|
|
||||||
include ':capacitor-mlkit-barcode-scanning'
|
include ':capacitor-mlkit-barcode-scanning'
|
||||||
project(':capacitor-mlkit-barcode-scanning').projectDir = new File('../node_modules/@capacitor-mlkit/barcode-scanning/android')
|
project(':capacitor-mlkit-barcode-scanning').projectDir = new File('../node_modules/@capacitor-mlkit/barcode-scanning/android')
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
BIN
assets/icon-only.jpg
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
assets/icon.png
|
Before Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
@@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"icon": {
|
|
||||||
"ios": {
|
|
||||||
"source": "resources/ios/icon/icon.png",
|
|
||||||
"target": "ios/App/App/Assets.xcassets/AppIcon.appiconset"
|
|
||||||
},
|
|
||||||
"android": {
|
|
||||||
"source": "resources/android/icon/icon.png",
|
|
||||||
"target": "android/app/src/main/res"
|
|
||||||
},
|
|
||||||
"web": {
|
|
||||||
"source": "resources/web/icon/icon.png",
|
|
||||||
"target": "public/img/icons"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"splash": {
|
|
||||||
"ios": {
|
|
||||||
"source": "resources/ios/splash/splash.png",
|
|
||||||
"target": "ios/App/App/Assets.xcassets/Splash.imageset"
|
|
||||||
},
|
|
||||||
"android": {
|
|
||||||
"source": "resources/android/splash/splash.png",
|
|
||||||
"target": "android/app/src/main/res"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"splashDark": {
|
|
||||||
"ios": {
|
|
||||||
"source": "resources/ios/splash/splash_dark.png",
|
|
||||||
"target": "ios/App/App/Assets.xcassets/SplashDark.imageset"
|
|
||||||
},
|
|
||||||
"android": {
|
|
||||||
"source": "resources/android/splash/splash_dark.png",
|
|
||||||
"target": "android/app/src/main/res"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
"appId": "app.timesafari",
|
"appId": "app.timesafari",
|
||||||
"appName": "TimeSafari",
|
"appName": "TimeSafari",
|
||||||
"webDir": "dist",
|
"webDir": "dist",
|
||||||
|
"bundledWebRuntime": false,
|
||||||
"server": {
|
"server": {
|
||||||
"cleartext": true
|
"cleartext": true
|
||||||
},
|
},
|
||||||
@@ -15,97 +16,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"SplashScreen": {
|
|
||||||
"launchShowDuration": 3000,
|
|
||||||
"launchAutoHide": true,
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"androidSplashResourceName": "splash",
|
|
||||||
"androidScaleType": "CENTER_CROP",
|
|
||||||
"showSpinner": false,
|
|
||||||
"androidSpinnerStyle": "large",
|
|
||||||
"iosSpinnerStyle": "small",
|
|
||||||
"spinnerColor": "#999999",
|
|
||||||
"splashFullScreen": true,
|
|
||||||
"splashImmersive": true
|
|
||||||
},
|
|
||||||
"CapacitorSQLite": {
|
|
||||||
"iosDatabaseLocation": "Library/CapacitorDatabase",
|
|
||||||
"iosIsEncryption": false,
|
|
||||||
"iosBiometric": {
|
|
||||||
"biometricAuth": false,
|
|
||||||
"biometricTitle": "Biometric login for TimeSafari"
|
|
||||||
},
|
|
||||||
"androidIsEncryption": false,
|
|
||||||
"androidBiometric": {
|
|
||||||
"biometricAuth": false,
|
|
||||||
"biometricTitle": "Biometric login for TimeSafari"
|
|
||||||
},
|
|
||||||
"electronIsEncryption": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ios": {
|
|
||||||
"contentInset": "never",
|
|
||||||
"allowsLinkPreview": true,
|
|
||||||
"scrollEnabled": true,
|
|
||||||
"limitsNavigationsToAppBoundDomains": true,
|
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"allowNavigation": [
|
|
||||||
"*.timesafari.app",
|
|
||||||
"*.jsdelivr.net",
|
|
||||||
"api.endorser.ch"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"android": {
|
|
||||||
"allowMixedContent": false,
|
|
||||||
"captureInput": true,
|
|
||||||
"webContentsDebuggingEnabled": false,
|
|
||||||
"allowNavigation": [
|
|
||||||
"*.timesafari.app",
|
|
||||||
"*.jsdelivr.net",
|
|
||||||
"api.endorser.ch"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"electron": {
|
|
||||||
"deepLinking": {
|
|
||||||
"schemes": ["timesafari"]
|
|
||||||
},
|
|
||||||
"buildOptions": {
|
|
||||||
"appId": "app.timesafari",
|
|
||||||
"productName": "TimeSafari",
|
|
||||||
"directories": {
|
|
||||||
"output": "dist-electron-packages"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist/**/*",
|
|
||||||
"electron/**/*"
|
|
||||||
],
|
|
||||||
"mac": {
|
|
||||||
"category": "public.app-category.productivity",
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "dmg",
|
|
||||||
"arch": ["x64", "arm64"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"win": {
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "nsis",
|
|
||||||
"arch": ["x64"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"target": [
|
|
||||||
{
|
|
||||||
"target": "AppImage",
|
|
||||||
"arch": ["x64"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"category": "Utility"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ try {
|
|||||||
- `src/interfaces/deepLinks.ts`: Type definitions and validation schemas
|
- `src/interfaces/deepLinks.ts`: Type definitions and validation schemas
|
||||||
- `src/services/deepLinks.ts`: Deep link processing service
|
- `src/services/deepLinks.ts`: Deep link processing service
|
||||||
- `src/main.capacitor.ts`: Capacitor integration
|
- `src/main.capacitor.ts`: Capacitor integration
|
||||||
- `src/views/DeepLinkRedirectView.vue`: Page to handle links to both mobile and web
|
|
||||||
|
|
||||||
## Type Safety Examples
|
## Type Safety Examples
|
||||||
|
|
||||||
|
|||||||
@@ -1,381 +0,0 @@
|
|||||||
# Worker-Only Database Implementation for Web Platform
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This implementation fixes the double migration issue in the TimeSafari web platform by implementing worker-only database access, similar to the Capacitor platform architecture.
|
|
||||||
|
|
||||||
## Problem Solved
|
|
||||||
|
|
||||||
**Before:** Web platform had dual database contexts:
|
|
||||||
|
|
||||||
- Worker thread: `registerSQLWorker.js` → `AbsurdSqlDatabaseService.initialize()` → migrations run
|
|
||||||
- Main thread: `WebPlatformService.dbQuery()` → `databaseService.query()` → migrations run **AGAIN**
|
|
||||||
|
|
||||||
**After:** Single database context:
|
|
||||||
|
|
||||||
- Worker thread: Handles ALL database operations and initializes once
|
|
||||||
- Main thread: Sends messages to worker, no direct database access
|
|
||||||
|
|
||||||
## Architecture Changes
|
|
||||||
|
|
||||||
### 1. Message-Based Communication
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Main Thread (WebPlatformService)
|
|
||||||
await this.sendWorkerMessage<QueryResult>({
|
|
||||||
type: "query",
|
|
||||||
sql: "SELECT * FROM users",
|
|
||||||
params: []
|
|
||||||
});
|
|
||||||
|
|
||||||
// Worker Thread (registerSQLWorker.js)
|
|
||||||
onmessage = async (event) => {
|
|
||||||
const { id, type, sql, params } = event.data;
|
|
||||||
if (type === "query") {
|
|
||||||
const result = await databaseService.query(sql, params);
|
|
||||||
postMessage({ id, type: "success", data: { result } });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Type-Safe Worker Messages
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/interfaces/worker-messages.ts
|
|
||||||
export interface QueryRequest extends BaseWorkerMessage {
|
|
||||||
type: "query";
|
|
||||||
sql: string;
|
|
||||||
params?: unknown[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WorkerRequest =
|
|
||||||
| QueryRequest
|
|
||||||
| ExecRequest
|
|
||||||
| GetOneRowRequest
|
|
||||||
| InitRequest
|
|
||||||
| PingRequest;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Circular Dependency Resolution
|
|
||||||
|
|
||||||
#### 🔥 Critical Fix: Stack Overflow Prevention
|
|
||||||
|
|
||||||
**Problem**: Circular module dependency caused infinite recursion:
|
|
||||||
|
|
||||||
- `WebPlatformService` constructor → creates Worker
|
|
||||||
- Worker loads `registerSQLWorker.js` → imports `databaseService`
|
|
||||||
- Module resolution creates circular dependency → Stack Overflow
|
|
||||||
|
|
||||||
**Solution**: Lazy Loading in Worker
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Before (caused stack overflow)
|
|
||||||
import databaseService from "./services/AbsurdSqlDatabaseService";
|
|
||||||
|
|
||||||
// After (fixed)
|
|
||||||
let databaseService = null;
|
|
||||||
|
|
||||||
async function getDatabaseService() {
|
|
||||||
if (!databaseService) {
|
|
||||||
// Dynamic import prevents circular dependency
|
|
||||||
const { default: service } = await import("./services/AbsurdSqlDatabaseService");
|
|
||||||
databaseService = service;
|
|
||||||
}
|
|
||||||
return databaseService;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Key Changes for Stack Overflow Fix:**
|
|
||||||
|
|
||||||
- ✅ Removed top-level import of database service
|
|
||||||
- ✅ Added lazy loading with dynamic import
|
|
||||||
- ✅ Updated all handlers to use `await getDatabaseService()`
|
|
||||||
- ✅ Removed auto-initialization that triggered immediate loading
|
|
||||||
- ✅ Database service only loads when first database operation occurs
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
### 1. WebPlatformService Changes
|
|
||||||
|
|
||||||
- Removed direct database imports
|
|
||||||
- Added worker message handling
|
|
||||||
- Implemented timeout and error handling
|
|
||||||
- All database methods now proxy to worker
|
|
||||||
|
|
||||||
### 2. Worker Thread Changes
|
|
||||||
|
|
||||||
- Added message-based operation handling
|
|
||||||
- Implemented lazy loading for database service
|
|
||||||
- Added proper error handling and response formatting
|
|
||||||
- Fixed circular dependency with dynamic imports
|
|
||||||
|
|
||||||
### 3. Main Thread Changes
|
|
||||||
|
|
||||||
- Removed duplicate worker creation in `main.web.ts`
|
|
||||||
- WebPlatformService now manages single worker instance
|
|
||||||
- Added Safari compatibility with `initBackend()`
|
|
||||||
|
|
||||||
## Files Modified
|
|
||||||
|
|
||||||
1. **src/interfaces/worker-messages.ts** *(NEW)*
|
|
||||||
- Type definitions for worker communication
|
|
||||||
- Request and response message interfaces
|
|
||||||
|
|
||||||
2. **src/registerSQLWorker.js** *(MAJOR REWRITE)*
|
|
||||||
- Message-based operation handling
|
|
||||||
- **Fixed circular dependency with lazy loading**
|
|
||||||
- Proper error handling and response formatting
|
|
||||||
|
|
||||||
3. **src/services/platforms/WebPlatformService.ts** *(MAJOR REWRITE)*
|
|
||||||
- Worker-only database access
|
|
||||||
- Message sending and response handling
|
|
||||||
- Timeout and error management
|
|
||||||
|
|
||||||
4. **src/main.web.ts** *(SIMPLIFIED)*
|
|
||||||
- Removed duplicate worker creation
|
|
||||||
- Simplified initialization flow
|
|
||||||
|
|
||||||
5. **WORKER_ONLY_DATABASE_IMPLEMENTATION.md** *(NEW)*
|
|
||||||
- Complete documentation of changes
|
|
||||||
|
|
||||||
## Benefits
|
|
||||||
|
|
||||||
### ✅ Fixes Double Migration Issue
|
|
||||||
|
|
||||||
- Database migrations now run only once in worker thread
|
|
||||||
- No duplicate initialization between main thread and worker
|
|
||||||
|
|
||||||
### ✅ Prevents Stack Overflow
|
|
||||||
|
|
||||||
- Circular dependency resolved with lazy loading
|
|
||||||
- Worker loads immediately without triggering database import
|
|
||||||
- Database service loads on-demand when first operation occurs
|
|
||||||
|
|
||||||
### ✅ Improved Performance
|
|
||||||
|
|
||||||
- Single database connection
|
|
||||||
- No redundant operations
|
|
||||||
- Better resource utilization
|
|
||||||
|
|
||||||
### ✅ Better Error Handling
|
|
||||||
|
|
||||||
- Centralized error handling in worker
|
|
||||||
- Type-safe message communication
|
|
||||||
- Proper timeout handling
|
|
||||||
|
|
||||||
### ✅ Consistent Architecture
|
|
||||||
|
|
||||||
- Matches Capacitor platform pattern
|
|
||||||
- Single-threaded database access
|
|
||||||
- Clear separation of concerns
|
|
||||||
|
|
||||||
## Testing Verification
|
|
||||||
|
|
||||||
After implementation, you should see:
|
|
||||||
|
|
||||||
1. **Worker Loading**:
|
|
||||||
|
|
||||||
```text
|
|
||||||
[SQLWorker] Worker loaded, ready to receive messages
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Database Initialization** (only on first operation):
|
|
||||||
|
|
||||||
```text
|
|
||||||
[SQLWorker] Starting database initialization...
|
|
||||||
[SQLWorker] Database initialization completed successfully
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **No Stack Overflow**: Application starts without infinite recursion
|
|
||||||
4. **Single Migration Run**: Database migrations execute only once
|
|
||||||
5. **Functional Database**: All queries, inserts, and updates work correctly
|
|
||||||
|
|
||||||
## Migration from Previous Implementation
|
|
||||||
|
|
||||||
If upgrading from the dual-context implementation:
|
|
||||||
|
|
||||||
1. **Remove Direct Database Imports**: No more `import databaseService` in main thread
|
|
||||||
2. **Update Database Calls**: Use platform service methods instead of direct database calls
|
|
||||||
3. **Handle Async Operations**: All database operations are now async message-based
|
|
||||||
4. **Error Handling**: Update error handling to work with worker responses
|
|
||||||
|
|
||||||
## Security Considerations
|
|
||||||
|
|
||||||
- Worker thread isolates database operations
|
|
||||||
- Message validation prevents malformed requests
|
|
||||||
- Timeout handling prevents hanging operations
|
|
||||||
- Type safety reduces runtime errors
|
|
||||||
|
|
||||||
## Performance Notes
|
|
||||||
|
|
||||||
- Initial worker creation has minimal overhead
|
|
||||||
- Database operations have message passing overhead (negligible)
|
|
||||||
- Single database connection is more efficient than dual connections
|
|
||||||
- Lazy loading reduces startup time
|
|
||||||
|
|
||||||
## Migration Execution Flow
|
|
||||||
|
|
||||||
### Before (Problematic)
|
|
||||||
|
|
||||||
```chart
|
|
||||||
┌────────────── ───┐ ┌─────────────────┐
|
|
||||||
│ Main Thread │ │ Worker Thread │
|
|
||||||
│ │ │ │
|
|
||||||
│ WebPlatformService│ │registerSQLWorker│
|
|
||||||
│ ↓ │ │ ↓ │
|
|
||||||
│ databaseService │ │ databaseService │
|
|
||||||
│ (Instance A) │ │ (Instance B) │
|
|
||||||
│ ↓ │ │ ↓ │
|
|
||||||
│ [Run Migrations] │ │[Run Migrations] │ ← DUPLICATE!
|
|
||||||
└─────────────── ──┘ └─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### After (Fixed)
|
|
||||||
|
|
||||||
```text
|
|
||||||
┌─────────────── ──┐ ┌─────────────────┐
|
|
||||||
│ Main Thread │ │ Worker Thread │
|
|
||||||
│ │ │ │
|
|
||||||
│ WebPlatformService │───→│registerSQLWorker│
|
|
||||||
│ │ │ ↓ │
|
|
||||||
│ [Send Messages] │ │ databaseService │
|
|
||||||
│ │ │(Single Instance)│
|
|
||||||
│ │ │ ↓ │
|
|
||||||
│ │ │[Run Migrations] │ ← ONCE ONLY!
|
|
||||||
└─────────────── ──┘ └─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## New Security Considerations
|
|
||||||
|
|
||||||
### 1. **Message Validation**
|
|
||||||
|
|
||||||
- All worker messages validated for required fields
|
|
||||||
- Unknown message types rejected with errors
|
|
||||||
- Proper error responses prevent information leakage
|
|
||||||
|
|
||||||
### 2. **Timeout Protection**
|
|
||||||
|
|
||||||
- 30-second timeout prevents hung operations
|
|
||||||
- Automatic cleanup of pending messages
|
|
||||||
- Worker health checks via ping/pong
|
|
||||||
|
|
||||||
### 3. **Error Sanitization**
|
|
||||||
|
|
||||||
- Error messages logged but not exposed raw to main thread
|
|
||||||
- Stack traces included only in development
|
|
||||||
- Graceful handling of worker failures
|
|
||||||
|
|
||||||
## Testing Considerations
|
|
||||||
|
|
||||||
### 1. **Unit Tests Needed**
|
|
||||||
|
|
||||||
- Worker message handling
|
|
||||||
- WebPlatformService worker communication
|
|
||||||
- Error handling and timeouts
|
|
||||||
- Migration execution (should run once only)
|
|
||||||
|
|
||||||
### 2. **Integration Tests**
|
|
||||||
|
|
||||||
- End-to-end database operations
|
|
||||||
- Worker lifecycle management
|
|
||||||
- Cross-browser compatibility (especially Safari)
|
|
||||||
|
|
||||||
### 3. **Performance Tests**
|
|
||||||
|
|
||||||
- Message passing overhead
|
|
||||||
- Database operation throughput
|
|
||||||
- Memory usage with worker communication
|
|
||||||
|
|
||||||
## Browser Compatibility
|
|
||||||
|
|
||||||
### 1. **Modern Browsers**
|
|
||||||
|
|
||||||
- Chrome/Edge: Full SharedArrayBuffer support
|
|
||||||
- Firefox: Full SharedArrayBuffer support (with headers)
|
|
||||||
- Safari: Uses IndexedDB fallback via `initBackend()`
|
|
||||||
|
|
||||||
### 2. **Required Headers**
|
|
||||||
|
|
||||||
```text
|
|
||||||
Cross-Origin-Opener-Policy: same-origin
|
|
||||||
Cross-Origin-Embedder-Policy: require-corp
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deployment Notes
|
|
||||||
|
|
||||||
### 1. **Development**
|
|
||||||
|
|
||||||
- Enhanced logging shows worker message flow
|
|
||||||
- Clear separation between worker and main thread logs
|
|
||||||
- Easy debugging via browser DevTools
|
|
||||||
|
|
||||||
### 2. **Production**
|
|
||||||
|
|
||||||
- Reduced logging overhead
|
|
||||||
- Optimized message passing
|
|
||||||
- Proper error reporting without sensitive data
|
|
||||||
|
|
||||||
## Future Enhancements
|
|
||||||
|
|
||||||
### 1. **Potential Optimizations**
|
|
||||||
|
|
||||||
- Message batching for bulk operations
|
|
||||||
- Connection pooling simulation
|
|
||||||
- Persistent worker state management
|
|
||||||
|
|
||||||
### 2. **Additional Features**
|
|
||||||
|
|
||||||
- Database backup/restore via worker
|
|
||||||
- Schema introspection commands
|
|
||||||
- Performance monitoring hooks
|
|
||||||
|
|
||||||
## Rollback Plan
|
|
||||||
|
|
||||||
If issues arise, rollback involves:
|
|
||||||
|
|
||||||
1. Restore original `WebPlatformService.ts`
|
|
||||||
2. Restore original `registerSQLWorker.js`
|
|
||||||
3. Restore original `main.web.ts`
|
|
||||||
4. Remove `worker-messages.ts` interface
|
|
||||||
|
|
||||||
## Commit Messages
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add src/interfaces/worker-messages.ts
|
|
||||||
git commit -m "Add worker message interface for type-safe database communication
|
|
||||||
|
|
||||||
- Define TypeScript interfaces for worker request/response messages
|
|
||||||
- Include query, exec, getOneRow, init, and ping message types
|
|
||||||
- Provide type safety for web platform worker messaging"
|
|
||||||
|
|
||||||
git add src/registerSQLWorker.js
|
|
||||||
git commit -m "Implement message-based worker for single-point database access
|
|
||||||
|
|
||||||
- Replace simple auto-init with comprehensive message handler
|
|
||||||
- Add support for query, exec, getOneRow, init, ping operations
|
|
||||||
- Implement proper error handling and response management
|
|
||||||
- Ensure single database initialization point to prevent double migrations"
|
|
||||||
|
|
||||||
git add src/services/platforms/WebPlatformService.ts
|
|
||||||
git commit -m "Migrate WebPlatformService to worker-only database access
|
|
||||||
|
|
||||||
- Remove direct databaseService import to prevent dual context issue
|
|
||||||
- Implement worker-based messaging for all database operations
|
|
||||||
- Add worker lifecycle management with initialization tracking
|
|
||||||
- Include message timeout and error handling for reliability
|
|
||||||
- Add Safari compatibility with initBackend call"
|
|
||||||
|
|
||||||
git add src/main.web.ts
|
|
||||||
git commit -m "Remove duplicate worker creation from main.web.ts
|
|
||||||
|
|
||||||
- Worker initialization now handled by WebPlatformService
|
|
||||||
- Prevents duplicate worker creation and database contexts
|
|
||||||
- Simplifies main thread initialization"
|
|
||||||
|
|
||||||
git add WORKER_ONLY_DATABASE_IMPLEMENTATION.md
|
|
||||||
git commit -m "Document worker-only database implementation
|
|
||||||
|
|
||||||
- Comprehensive documentation of architecture changes
|
|
||||||
- Explain problem solved and benefits achieved
|
|
||||||
- Include security considerations and testing requirements"
|
|
||||||
```
|
|
||||||