Skip to content

Commit

Permalink
Merge branch 'BasedHardware:main' into firmware-flashing-readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ebowwa authored Sep 13, 2024
2 parents cf754ae + 591b30d commit f2c253a
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 100 deletions.
1 change: 0 additions & 1 deletion app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import 'package:gleap_sdk/gleap_sdk.dart';
import 'package:instabug_flutter/instabug_flutter.dart';
import 'package:opus_dart/opus_dart.dart';
import 'package:opus_flutter/opus_flutter.dart' as opus_flutter;
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:talker_flutter/talker_flutter.dart';

Expand Down
2 changes: 1 addition & 1 deletion app/lib/pages/capture/_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class CapturePageState extends State<CapturePage> with AutomaticKeepAliveClientM
FlutterForegroundTask.addTaskDataCallback(_onReceiveTaskData);
WidgetsBinding.instance.addObserver(this);
SchedulerBinding.instance.addPostFrameCallback((_) async {
await context.read<CaptureProvider>().processCachedTranscript();
// await context.read<CaptureProvider>().processCachedTranscript();
if (context.read<DeviceProvider>().connectedDevice != null) {
context.read<OnboardingProvider>().stopFindDeviceTimer();
}
Expand Down
6 changes: 4 additions & 2 deletions app/lib/pages/home/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver, Ticker
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_) async {
_initiatePlugins();
ForegroundUtil.requestPermissions();
// ForegroundUtil.requestPermissions();
await ForegroundUtil.initializeForegroundService();
ForegroundUtil.startForegroundTask();
if (mounted) {
Expand Down Expand Up @@ -203,7 +203,9 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver, Ticker
actions: [
TextButton(
onPressed: () {
ScaffoldMessenger.of(ctx).hideCurrentMaterialBanner();
if (mounted) {
ScaffoldMessenger.of(ctx).hideCurrentMaterialBanner();
}
},
child: const Text('Dismiss'),
),
Expand Down
79 changes: 62 additions & 17 deletions app/lib/pages/onboarding/permissions/notification_permission.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:friend_private/providers/onboarding_provider.dart';
import 'package:friend_private/widgets/dialog.dart';
Expand All @@ -22,6 +24,27 @@ class _NotificationPermissionWidgetState extends State<NotificationPermissionWid
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Platform.isAndroid
? CheckboxListTile(
value: provider.hasBackgroundPermission,
onChanged: (s) async {
if (s != null) {
if (s) {
await provider.askForBackgroundPermissions();
} else {
provider.updateBackgroundPermission(false);
}
}
},
title: const Text(
'Allow Omi to run in the background to improve stability',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
contentPadding: const EdgeInsets.only(left: 8),
// controlAffinity: ListTileControlAffinity.leading,
checkboxShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
)
: const SizedBox.shrink(),
CheckboxListTile(
value: provider.hasNotificationPermission,
onChanged: (s) async {
Expand Down Expand Up @@ -62,24 +85,46 @@ class _NotificationPermissionWidgetState extends State<NotificationPermissionWid
child: MaterialButton(
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
onPressed: () {
if (provider.hasNotificationPermission) {
widget.goNext();
if (Platform.isAndroid) {
if (provider.hasNotificationPermission && provider.hasBackgroundPermission) {
widget.goNext();
} else {
showDialog(
context: context,
builder: (c) => getDialog(
context,
() {
Navigator.of(context).pop();
},
() {
Navigator.of(context).pop();
},
'Allow Permissions',
'This app needs notification and background permissions to improve your experience.',
singleButton: true,
),
);
}
} else {
showDialog(
context: context,
builder: (c) => getDialog(
context,
() {
Navigator.of(context).pop();
},
() {
Navigator.of(context).pop();
},
'Allow Notifications',
'This app needs notification permissions to improve your experience.',
singleButton: true,
),
);
if (provider.hasNotificationPermission) {
widget.goNext();
} else {
showDialog(
context: context,
builder: (c) => getDialog(
context,
() {
Navigator.of(context).pop();
},
() {
Navigator.of(context).pop();
},
'Allow Notifications',
'This app needs notification permissions to improve your experience.',
singleButton: true,
),
);
}
}
},
child: const Text(
Expand Down
15 changes: 15 additions & 0 deletions app/lib/providers/onboarding_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:friend_private/providers/base_provider.dart';
import 'package:friend_private/providers/device_provider.dart';
import 'package:friend_private/services/notification_service.dart';
import 'package:friend_private/utils/analytics/mixpanel.dart';
import 'package:friend_private/utils/audio/foreground.dart';
import 'package:friend_private/utils/ble/connect.dart';
import 'package:friend_private/utils/ble/connected.dart';
import 'package:friend_private/utils/ble/find.dart';
Expand All @@ -36,6 +37,7 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin {
bool hasBluetoothPermission = false;
bool hasLocationPermission = false;
bool hasNotificationPermission = false;
bool hasBackgroundPermission = false; // Android only

Future updatePermissions() async {
hasBluetoothPermission = await Permission.bluetooth.isGranted;
Expand Down Expand Up @@ -65,6 +67,12 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin {
notifyListeners();
}

void updateBackgroundPermission(bool value) {
hasBackgroundPermission = value;
MixpanelManager().setUserProperty('Background Permission Enabled', hasBackgroundPermission);
notifyListeners();
}

Future askForBluetoothPermissions() async {
FlutterBluePlus.setLogLevel(LogLevel.info, color: true);
if (Platform.isIOS) {
Expand Down Expand Up @@ -98,6 +106,13 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin {
updateNotificationPermission(isAllowed);
notifyListeners();
}

Future askForBackgroundPermissions() async {
await ForegroundUtil.requestPermissions();
var isAllowed = await ForegroundUtil().isIgnoringBatteryOptimizations;
updateBackgroundPermission(isAllowed);
notifyListeners();
}
//----------------- Onboarding Permissions -----------------

void stopFindDeviceTimer() {
Expand Down
2 changes: 2 additions & 0 deletions app/lib/utils/audio/foreground.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class ForegroundUtil {
}
}

Future<bool> get isIgnoringBatteryOptimizations async => await FlutterForegroundTask.isIgnoringBatteryOptimizations;

static Future<void> initializeForegroundService() async {
if (await FlutterForegroundTask.isRunningService) return;
debugPrint('initializeForegroundService');
Expand Down
6 changes: 3 additions & 3 deletions app/lib/utils/ble/gatt_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ const String buttonTriggerCharacteristicUuid = '23ba7925-0000-1000-7450-346eac49
const String imageDataStreamCharacteristicUuid = '19b10005-e8f2-537e-4f6c-d104768a1214';
const String imageCaptureControlCharacteristicUuid = '19b10006-e8f2-537e-4f6c-d104768a1214';


const String storageDataStreamServiceUuid = '30295780-4301-eabd-2904-2849adfeae43';
const String storageDataStreamCharacteristicUuid = '30295781-4301-eabd-2904-2849adfeae43';
const String storageReadControlCharacteristicUuid = '30295782-4301-eabd-2904-2849adfeae43';

const String accelDataStreamServiceUuid = '32403790-0000-1000-7450-bf445e5829a2';
const String accelDataStreamCharacteristicUuid = '32403791-0000-1000-7450-bf445e5829a2';
const String accelDataStreamServiceUuid = '32403790-0000-1000-7450-bf445e5829a2';
const String accelDataStreamCharacteristicUuid = '32403791-0000-1000-7450-bf445e5829a2';

const String batteryServiceUuid = '0000180f-0000-1000-8000-00805f9b34fb';
const String batteryLevelCharacteristicUuid = '00002a19-0000-1000-8000-00805f9b34fb';
Expand All @@ -46,6 +45,7 @@ Future<List<BluetoothService>> getBleServices(String deviceId) async {
} else {
// TODO: need to be fixed for open glass
// if (Platform.isAndroid && device.servicesList.isNotEmpty) return device.servicesList;
if (device.servicesList.isNotEmpty) return device.servicesList;
return await device.discoverServices();
}
} catch (e, stackTrace) {
Expand Down
65 changes: 37 additions & 28 deletions backend/database/trends.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,49 @@
from datetime import datetime
from typing import Dict, List

from firebase_admin import firestore
from google.api_core.retry import Retry
from google.cloud.firestore_v1 import FieldFilter

from models.memory import Memory
from models.trend import Trend
from ._client import db
from ._client import db, document_id_from_seed


def get_trends_data() -> List[Dict[str, Trend]]:
def get_trends_data() -> List[Dict]:
trends_ref = db.collection('trends')
trends_docs = [doc for doc in trends_ref.stream(retry=Retry())]
trends_list = []
for doc in trends_docs:
trend = doc.to_dict()
trend['id'] = doc.id
trend['name'] = trend['name']
trend['created_at'] = str(trend['created_at'])
data = doc.reference.collection('data').count().get()[0][0].value
trend['data'] = data
trends_list.append({trend['name']: trend})
print(f"{{'{trend['name']}' : {trend}}}")
return trends_list


def save_trends(memory: Memory, trends: List[str]):
mem_data = {
'date': memory.created_at,
'memory_id': memory.id
}
print(f"trend_data: {mem_data}")
trends_ref = db.collection('trends')
trends_data = []
for category in trends_docs:
category_data = category.to_dict()

category_topics_ref = trends_ref.document(category_data['id']).collection('topics')
topics_docs = [topic.to_dict() for topic in category_topics_ref.stream(retry=Retry())]
topics = sorted(topics_docs, key=lambda e: len(e['memory_ids']), reverse=True)
for topic in topics:
topic['memories_count'] = len(topic['memory_ids'])
del topic['memory_ids']

category_data['topics'] = topics
trends_data.append(category_data)
return trends_data


def save_trends(memory: Memory, trends: List[Trend]):
trends_coll_ref = db.collection('trends')

for trend in trends:
trend_ref = trends_ref.where(filter=FieldFilter('name', '==', trend)).get()
if len(trend_ref) == 0:
trends_ref.add({"created_at": datetime.now(), "name": trend})
trend_ref = trends_ref.where(filter=FieldFilter('name', '==', trend)).get()
trend_ref[0].reference.collection('data').add(mem_data)
category = trend.category.value
topics = trend.topics
category_id = document_id_from_seed(category)
category_doc_ref = trends_coll_ref.document(category_id)

category_doc_ref.set({"id": category_id, "category": category, "created_at": datetime.utcnow()}, merge=True)

topics_coll_ref = category_doc_ref.collection('topics')

for topic in topics:
topic_id = document_id_from_seed(topic)
topic_doc_ref = topics_coll_ref.document(topic_id)

topic_doc_ref.set({"id": topic_id, "topic": topic}, merge=True)
topic_doc_ref.update({'memory_ids': firestore.firestore.ArrayUnion([memory.id])})
32 changes: 15 additions & 17 deletions backend/models/trend.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
from datetime import datetime
from enum import Enum
from typing import List

from pydantic import BaseModel
from pydantic import BaseModel, Field


class TrendEnum(str, Enum):
health = 'health'
finance = 'finance'
science = 'science'
entrepreneurship = 'entrepreneurship'
technology = 'technology'
sports = 'sports'


class TrendData(BaseModel):
memory_id: str
date: datetime
acquisition = "acquisition"
ceo = "ceo"
company = "company"
event = "event"
founder = "founder"
industry = "industry"
innovation = "innovation"
investment = "investment"
partnership = "partnership"
product = "product"
research = "research"
tool = "tool"


class Trend(BaseModel):
id: str
name: str
created_at: datetime
data: int
category: TrendEnum = Field(description="The category identified")
topics: List[str] = Field(description="The specific topic corresponding the category")
13 changes: 6 additions & 7 deletions backend/routers/trends.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from typing import Dict, List
from typing import List

import database.trends as trends_db
from fastapi import APIRouter
from models.trend import Trend

import database.trends as trends_db

router = APIRouter()


@router.get("/v1/trends", response_model=List[Dict[str, Trend]], tags=['trends'])
def get_trends(offset: int = 0, limit: int = 10):
trends = trends_db.get_trends_data()
return trends
@router.get("/v1/trends", response_model=List, tags=['trends'])
def get_trends():
return trends_db.get_trends_data()
Loading

0 comments on commit f2c253a

Please sign in to comment.