Procházet zdrojové kódy

cleaned up voice flow, removed wakework

cdmoss před 2 roky
rodič
revize
7b5594b0ae

+ 2 - 2
android/build.gradle

@@ -4,8 +4,8 @@ buildscript {
     ext {
         buildToolsVersion = "29.0.3"
         minSdkVersion = 21
-        compileSdkVersion = 31
-        targetSdkVersion = 31
+        compileSdkVersion = 32
+        targetSdkVersion = 32
         kotlinVersion = "1.6.0"
     }
     repositories {

+ 8 - 11
src/components/Map/IndoorFloor.tsx

@@ -1,26 +1,23 @@
-import { View, Text } from 'react-native'
 import React from 'react'
 import { Image } from 'react-native-svg'
-import BasementC from './MainMapComponent/images/BasementC.svg'
-import FirstFloorC from './MainMapComponent/images/FirstFloorC.svg'
-import SecondFloorC from './MainMapComponent/images/SecondFloorC.svg'
-import ThirdFloorC from './MainMapComponent/images/ThirdFloorC.svg'
-import FourthFloorC from './MainMapComponent/images/FourthFloorC.svg'
-import FifthFloorC from './MainMapComponent/images/FifthFloorC.svg'
 
-// export const IndoorFloor: React.FC<{floorNum: number}> = (props) => {
+interface Building {
+  id: number
+  name: string
+  floors: number
+}
+
 function IndoorFloor(props) {
-  const compArray = [
+  const floors = [
     <Image height={"100%"} width={"100%"} href={require('./MainMapComponent/images/basement.png')} />,
     <Image height={'100%'} width="100%" href={require('./MainMapComponent/images/firstfloor.png')} />,
     <Image height={"100%"} width={"100%"} href={require('./MainMapComponent/images/secondfloor.png')} />,
     <Image height={"100%"} width={"100%"} href={require('./MainMapComponent/images/thirdfloor.png')} />,
     <Image height={"100%"} width={"100%"} href={require('./MainMapComponent/images/fourthfloor.png')} />,
     <Image height={"100%"} width={"100%"} href={require('./MainMapComponent/images/fifthfloor.png')} />,
-    // <FifthFloorC viewBox='257 153 270 290' style={{ opacity: 0.7 }} height={"100%"} width={"100%"} />,
   ]
 
-  return compArray[props.floorNum]
+  return floors[props.floorNum]
 }
 
 export default IndoorFloor

+ 14 - 85
src/components/Map/MainMapComponent/IndoorMap.tsx

@@ -1,23 +1,15 @@
-import React, { useState, useEffect, Children } from 'react';
-import { View, Text, StatusBar, StyleSheet, Dimensions, Button, ActivityIndicator, Alert, Modal, PanResponderCallbacks, PanResponderGestureState, GestureResponderEvent, ImageSourcePropType, TouchableOpacity, Platform, Linking, Pressable, } from 'react-native';
-import { Svg, Defs, Rect, Mask, Circle, Marker, Path, Polyline, Image } from 'react-native-svg';
-import { RadioButton } from 'react-native-paper';
-import { Picker as EricPicker } from '@react-native-picker/picker';
-import ReactNativeZoomableView from '@openspacelabs/react-native-zoomable-view/src/ReactNativeZoomableView';
-import Spinner from 'react-native-spinkit'
-import { colors, lmTypesIndoor } from "../../../utils/GlobalUtils";
-import { MapStackNavigationProp } from "../../../navigation/MapNavigator"
-import CustomModal from './modal';
 import { FontAwesome } from "@expo/vector-icons";
-import ReactDOMServer from 'react-dom/server'; //npm i --save-dev @types/react-dom
-import { ZoomableViewEvent } from '@openspacelabs/react-native-zoomable-view/src/typings';
-import IndoorFloor from '../IndoorFloor'
-// import Toast from 'react-native-toast-message';
-import Toast from 'react-native-root-toast';
-import ArrowButton from './ArrowButton'
-import BottomButtons from './BottomButtons'
+import ReactNativeZoomableView from '@openspacelabs/react-native-zoomable-view/src/ReactNativeZoomableView';
+import React, { useEffect, useState } from 'react';
+import { ActivityIndicator, Alert, Dimensions, GestureResponderEvent, ImageSourcePropType, StatusBar, StyleSheet, View } from 'react-native';
 import Picker from 'react-native-picker-select';
+import Toast from 'react-native-root-toast';
+import { Image, Rect, Svg } from 'react-native-svg';
 import { Landmark } from '../../../data/landmarks';
+import { MapStackNavigationProp } from "../../../navigation/MapNavigator";
+import { colors, lmTypesIndoor } from "../../../utils/GlobalUtils";
+import IndoorFloor from '../IndoorFloor';
+import ArrowButton from './ArrowButton';
 
 
 
@@ -32,11 +24,9 @@ interface IndoorMapProps {
 
 
 
-const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddLandmark, focusLandmark, applyFilter }) => {
+const IndoorMap: React.FC<IndoorMapProps> = ({ landmarks, promptAddLandmark, focusLandmark, applyFilter }) => {
   const [floor, setFloor] = useState(1);
   const [showME, setShowME] = useState(false);
-  const [showDots, setShowDots] = useState(false);
-  const [showAddedDot, setShowAddedDot] = useState(false)
   const [SVGdim, setSVGdim] = useState([1, 1])
 
   const [localLandmarks, setLocalLandmarks] = useState<Landmark[]>([])
@@ -59,8 +49,7 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
           href={lmTypesIndoor[item.landmark_type].image as ImageSourcePropType} />
       )
     }
-  }
-  )
+  })
 
 
   function addLandmark(evt: GestureResponderEvent) {
@@ -87,9 +76,7 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
 
   useEffect(() => {
     // Alert.alert("useEffect has been triggered")
-    setShowAddedDot(false)
-    setShowDots(false)
-    setTimeout(() => setShowME(true), 100);
+    setTimeout(() => setShowME(true), 50);
   })
 
   const childToWeb = (child: any) => {
@@ -101,23 +88,6 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
   };
 
   const toWeb = (children: any) => React.Children.map(children, childToWeb);
-
-  function renderSvg() {
-    return (
-      <Svg height="100%" width="100%" style={{ backgroundColor: '#33AAFF' }}>
-        <Rect
-          x="50"
-          y="50"
-          width="50"
-          height="50"
-          fill="#3399ff"
-          strokeWidth="3"
-          stroke="rgb(0,0,0)"
-        />
-      </Svg>
-    )
-  }
-
   function changer(num) {
     setFloor(prevState => prevState + num)
   }
@@ -127,7 +97,7 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
     <View style={{ height: '100%', width: Dimensions.get("screen").width, backgroundColor:colors.red }}>
 
       <StatusBar backgroundColor={colors.red} />
-      <CustomModal />
+      {/* <CustomModal /> */}
       {/* <Text style={{ fontSize: 16, marginBottom: 5 }}>Please select a floor you would like to go to.</Text> */}
 
       <View style={{ borderColor: "blue", borderWidth: 0, maxHeight: 50, flex: 1, flexDirection: "row", justifyContent: "center", }}>
@@ -162,23 +132,6 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
         </View>
 
 
-        {/* <EricPicker
-          style={{ backgroundColor: colors.red, width: 200, height: 50, flex: 5, color: 'white' }}
-          selectedValue={floor} // the text of what gets displayed on the dropdown header
-          onValueChange={(itemValue, itemIndex: number) => {
-            setFloor(itemIndex)
-            setShowME(false)
-          }}>
-          The value in EricPicker.Item refers to selectedValue in EricPicker, which refers to the state "floor"
-          <EricPicker.Item label="Basement" value={0} />
-          <EricPicker.Item label="First Floor" value={1} />
-          <EricPicker.Item label="Second Floor" value={2} />
-          <EricPicker.Item label="Third Floor" value={3} />
-          <EricPicker.Item label="Fourth Floor" value={4} />
-          <EricPicker.Item label="Fifth Floor" value={5} />
-        </EricPicker> */}
-
-
         {/* {floor == 5 ? arrowBut(0, "") : arrowBut(1, "chevron-right")} */}
         {floor == 5 ? <ArrowButton num={0} fontAweIcon={""} /> : <ArrowButton num={1} fontAweIcon={"chevron-right"} propEvent={() => changer(1)} />}
 
@@ -189,7 +142,7 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
         <View style={styles.container}>
           {showME === false ?
             <View style={{ display: 'flex', flexDirection: 'row', justifyContent: "center", }}>
-              <Spinner size={200} color={colors.red} type="9CubeGrid" />
+              <ActivityIndicator color={colors.red} size="large" />
             </View> :
 
             <ReactNativeZoomableView
@@ -227,22 +180,6 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
 
         </View>
       </View>
-      {/* <Button title="load coordinates" onPress={() => {
-        setfirstTime(false)
-        setLocalLandmarks(landmarks)
-      }} /> */}
-
-      {/* <Button title='Press me to svgString' color={colors.red} onPress={serialize}></Button> */}
-      {/* <View style={{ flex: 0.1, flexDirection: 'row', alignItems:'flex-end', justifyContent: 'space-around' , borderColor:'green' , borderWidth:0 ,}}>
-      <Button title="Go back to map" color={colors.red} onPress={() => navigation.goBack()} />
-      <Button title="Resources" color={colors.red} onPress={() => Linking.openURL('https://www.library.ualberta.ca/')} />
-      </View> */}
-      {/* <TouchableOpacity style={styles.arrowButton} onPress={() => setFloor(prevState => prevState+1)} ><Text>Increase floor by 1</Text></TouchableOpacity> */}
-
-
-      {/* <BottomButtons navigation={navigation}/> */}
-      {/* <Text>{floor}</Text> */}
-
     </View >
   );
 }
@@ -256,12 +193,6 @@ const styles = StyleSheet.create({
     borderWidth: 0,
     marginVertical: 0,
     aspectRatio: 8 / 10,  // (caters to portrait mode) (width is 80% the value of height dimension)
-    // flex: 1,
-    // // backgroundColor: "#fff",
-    // justifyContent: "center",
-    // borderColor: "black",
-    // borderWidth: 2,
-    // marginVertical: 15,
     width: '100%',
     height: '100%',
     maxWidth: "100%",
@@ -280,9 +211,7 @@ const styles = StyleSheet.create({
   arrowButton: {
     flex: 1,
     backgroundColor: colors.red,
-    // backgroundColor: "blue",
     height: 53.5,
-    // borderRadius: 10,
   },
 });
 

+ 25 - 16
src/components/Map/Panels/VoicePanel.tsx

@@ -58,6 +58,12 @@ export interface VoiceAction {
  * @param 
  * @returns 
  */
+
+const activateSpokestack = async (sourceCall: string) => {
+    await Spokestack.activate();
+    console.log("Spokestack activated from: " + sourceCall);
+}
+
 export const VoicePanel: React.FC<VoicePanelProps> = ({
         navigation,
         toggleVoiceVisible, 
@@ -181,13 +187,13 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
             '1A8196594C401EB93035CC6D7D6328CF1855C2B359744E720953AC34B6F658CA', // api token
             {
                 pipeline: {
-                    profile: PipelineProfile.TFLITE_WAKEWORD_NATIVE_ASR
-                },
-                wakeword: {
-                    detect: 'https://s.spokestack.io/u/kHNUa/detect.tflite',
-                    filter: 'https://s.spokestack.io/u/kHNUa/filter.tflite',
-                    encode: 'https://s.spokestack.io/u/kHNUa/encode.tflite',
+                    profile: PipelineProfile.PTT_NATIVE_ASR
                 },
+                // wakeword: {
+                //     detect: 'https://s.spokestack.io/u/kHNUa/detect.tflite',
+                //     filter: 'https://s.spokestack.io/u/kHNUa/filter.tflite',
+                //     encode: 'https://s.spokestack.io/u/kHNUa/encode.tflite',
+                // },
             }
         ).then(Spokestack.start).catch(error => console.log("[Voice]: Something went wrong when starting spokestack: " + error))
 
@@ -211,7 +217,7 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
                 else if (!speechResult && !listening && action) {
                     console.log('[Voice]: No speech result detected, but an action is in progress')
                     setListening(true)
-                    await Spokestack.activate()
+                    
                 }
                 else if (!speechResult && !listening) {
                     await closeVoice()
@@ -242,7 +248,7 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
         // handle unrecognized result
         else {
             setResponse("Did not recognize command, please try again")
-            await Spokestack.activate();
+            await activateSpokestack('processSpeechTranscript');
         }
     }
 
@@ -269,7 +275,7 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
         else {
             setResponse("Did not recognize command, please try again")
         }
-        await Spokestack.activate()
+        await activateSpokestack("discernActionRequest");
     }
 
     // action initiators
@@ -277,7 +283,7 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
     const initiateAddLandmarkAction = async () => {
         setNewLandmark({longitude: userCoords.longitude, latitude: userCoords.latitude})
         setAction({actionType: "Add landmark", actionStep: 1})
-        await Spokestack.activate();
+        await activateSpokestack("initiateAddLandmarkAction");
     }   
 
     const initiateViewNearLandmarksAction = async () => {
@@ -289,7 +295,7 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
         // tell user there is no landmarks
         else {
             setResponse("There are no landmarks nearby")
-            await Spokestack.activate();
+            await activateSpokestack("initiateViewNearLandmarksAction");
         }
     }
 
@@ -308,7 +314,7 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
         else {
         }
 
-        await Spokestack.activate();
+        await activateSpokestack("performActionFlow");
     }
 
 // action flows
@@ -382,11 +388,14 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
         const finishAddAttempt = async () => {
             if (addLandmarkMutation.isSuccess) {
                 addLandmarkMutation.reset();
-                setSelectedLandmarkId(newLandmark.id)
-                await Spokestack.activate();
+                setAlert({
+                    title: "Added landmark", 
+                    message: "Landmark added successfully", 
+                    type: "success",
+                })
             }
             else if (addLandmarkMutation.isError) {
-                await Spokestack.activate();
+                await activateSpokestack("finishAddAttempt");
             }
         }
         finishAddAttempt();
@@ -397,13 +406,13 @@ export const VoicePanel: React.FC<VoicePanelProps> = ({
 // end action flows
     
     const closeVoice = async () => {
-        await Spokestack.deactivate();
         setSpeechResult('')
         setPreviousResult('')
         setResponse('')
         setListening(false)
         setAction(undefined);
         toggleVoiceVisible(false)
+        await Spokestack.deactivate();
     }
 
     const LmTypeDisplay: React.FC<{lmType: {image: ImageRequireSource, label:string}, style?: ViewStyle}> = ({lmType, style}) => {

+ 4 - 5
src/components/Profile/LoginView.tsx

@@ -6,20 +6,19 @@
  */
 
 import { makeRedirectUri } from "expo-auth-session";
+import * as Linking from 'expo-linking';
 import * as WebBrowser from 'expo-web-browser';
 import { maybeCompleteAuthSession } from "expo-web-browser";
 import React, { useState } from "react";
-import { ActivityIndicator, Image, Pressable, StyleSheet, Text, TouchableHighlight, TouchableOpacity, View } from "react-native";
+import { ActivityIndicator, Image, StyleSheet, Text, TouchableOpacity, View } from "react-native";
+import Collapsible from "react-native-collapsible";
 import { useAuth } from "../../data/Auth/AuthContext";
 import { BaseStackNavigationProp } from "../../navigation/BaseStackNavigator";
 import { API_URL } from "../../utils/RequestUtils";
 import { GenericButton, PrimaryButton } from "../Buttons";
-import { ProfileSectionHeader } from "./ProfileSections/ProfileSectionHeader";
-import * as Linking from 'expo-linking';
-import { BrowserLink, ProfileLegal } from "./ProfileSections/ProfileLegal";
 import { Separator } from "../Separator";
-import Collapsible from "react-native-collapsible";
 import UnauthorizedLayout from "./AuthLayout";
+import { BrowserLink } from "./ProfileSections/ProfileLegal";
 
 /**
  * Props used by the {@link Intro} screen.

+ 27 - 0
src/data/buildings.ts

@@ -0,0 +1,27 @@
+export interface Space {
+    
+}
+
+export interface Building {
+    id: number;
+    name: string;
+    floors: BuildingFloor[];
+    polygon: string
+}
+
+export interface BuildingFloor {
+    id: number;
+    number: number;
+    map: string;
+    building: string
+    landmarks
+}
+
+export interface BuildingResource {
+    id: number;
+    label: string;
+    content: string
+    building: string;
+
+}
+

+ 2 - 1
src/utils/RequestUtils.ts

@@ -11,7 +11,8 @@
 //export const API_URL = 'http://192.168.3.81:8000'
 // export const API_URL = 'https://staging.clicknpush.ca'
 
-export const API_URL = 'http://192.168.1.70:8000'   // Chase
+//export const API_URL = 'https://app.clicknpush.ca'
+export const API_URL = 'http://192.168.1.64:8000'   // Chase
 //export const API_URL = 'http://192.168.0.22:8000'       // Eric
 //export const API_URL = 'https://app.clicknpush.ca'
 

+ 1 - 0
src/utils/logging.ts

@@ -2,6 +2,7 @@ export interface Logging {
     log: (category: LogCategory, message: string, type?: Logtype) => void;
     CATEGORIES: { [key: string]: LogCategory };
 }
+
 export type LogCategory = "SYSTEM" | "AUTH" | 'NOTIFICATIONS' | 'LANDMARKS' | 'COMMENTS' | 'PROFILE';
 export type Logtype = "error" | "warning" | "info"