diff --git a/API.js b/API.js
new file mode 100644
index 0000000..4160970
--- /dev/null
+++ b/API.js
@@ -0,0 +1,251 @@
+const baseUrl = "https://api.emmint.com";
+
+let getCall = async (path = "", params = {}) => {
+ let queryParams = "?";
+ Object.keys(params).forEach(p => {
+ queryParams += p + "=" + params[p] + "&"
+ });
+ return fetch(baseUrl + path + queryParams, {
+ method: 'GET',
+ mode: 'cors',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
+ }
+ }).then(response => response.json()).catch((error) => {
+ console.error(error);
+ })
+}
+
+let postCall = async (path, params) => {
+ return fetch(baseUrl + path, {
+ method: 'POST',
+ mode: 'cors',
+ credentials: 'include',
+ body: JSON.stringify(params),
+ headers: {
+ 'Content-Type': 'application/json',
+ }
+ }).then(response => response.json()).catch((error) => {
+ console.error(error);
+ })
+}
+
+let CurrentUserId;
+let CurrentProfile;
+let CurrentProfileData;
+let userNameCache = {}; //save this on localstorage
+let working_on = {}; //Promises
+let getProfileFromCache = async (id, refresh=false) => {
+ if(!id) console.trace();
+ if (userNameCache[id] && !refresh)
+ return userNameCache[id];
+ if (working_on[id] && !refresh)
+ return working_on[id];
+ console.log(id, "not in cache, getting...")
+ working_on[id] = getCall("/user/" + id)
+ return working_on[id];
+}
+
+const API = {
+ isLoggedIn: async () => {
+ return getCall().then((data) => {
+ console.log("isLoggedIn", data)
+ if (data && data.status && data.status === 'ok') {
+ CurrentUserId = data.userInfo._id;
+ CurrentProfile = data.profileInfo._id;
+ return true;
+ }
+ CurrentUserId = '';
+ CurrentProfile = '';
+ CurrentProfileData = undefined;
+ return false;
+ })
+ },
+ logIn: async (username, password) => {
+ return postCall("/login", {
+ username,
+ password
+ }).then((data) => {
+ if (data && data.status === "ok") {
+ CurrentUserId = data.user_sid;
+ CurrentProfile = data.profile_id;
+ }
+ return data;
+ })
+ },
+ async logout(){
+ console.log("Logging out...")
+ return getCall("/logout").then(()=>{
+ CurrentUserId = '';
+ CurrentProfile = '';
+ CurrentProfileData = undefined;
+ });
+ },
+ async signup(username, password, email, profile){
+ return postCall("/signup", {
+ username,
+ password,
+ email,
+ profile
+ }).then((data) => {
+ console.log(data)
+ if (data && data.status === "ok") {
+ CurrentUserId = data.user_sid;
+ CurrentProfile = data.profile_id;
+ }
+ return data;
+ });
+ },
+ resetPassword(email){
+ return postCall("/resetPassword", {username: email});
+ },
+ currentUserId() {
+ if (!CurrentUserId) this.isLoggedIn(); //replace with cookie
+ return CurrentUserId;
+ },
+ addPaymentCard(cardInfo){
+ return postCall("/payment/card", {cardInfo});
+ },
+ //Posts
+ getPosts(userid) {
+ if (userid) return getCall("/post/usr/" + userid);
+ return getCall("/post/");
+ },
+ newPost(content, toProfile) {
+ //Content is expected to be a string.
+ let params = { content };
+ if (toProfile && CurrentUserId !== toProfile)
+ params.toProfile = toProfile;
+ return postCall("/post/", params);
+ },
+ newPostReaction(postid) {
+ return postCall("/post/react", { postid });
+ },
+ removePostReaction(postid) {
+ return postCall("/post/unreact", { postid });
+ },
+ newPostBookmark(postid) {
+ return postCall("/post/bookmark", { postid });
+ },
+ removePostBookmark(postid) {
+ return postCall("/post/unbookmark", { postid });
+ },
+ newPostComment(postid, content) {
+ return postCall("/post/comment/", { postid, content });
+ },
+ newCommentReaction(postid, commentDate) {
+ return postCall("/post/comment/react", { postid, commentDate });
+ },
+ //Invitations
+ newInvitation(name, email){
+ return postCall("/user/invite", { name, email });
+ },
+ getInvitation(email){
+ return getCall("/user/invite", { email });
+ },
+ //Profiles
+ async getMe() {
+ if (!CurrentProfileData)
+ if(!CurrentProfile) await this.isLoggedIn();
+ CurrentProfileData = await this.getUserProfile(CurrentProfile);
+ return CurrentProfileData;
+ },
+ getMyProfiles() {
+ return getCall("/user/mine");
+ },
+ getMyProfile() {
+ return getCall("/user/" + CurrentProfile);
+ },
+ updateMyProfile(profile) {
+ return postCall("/user/myProfile", profile);
+ },
+ searchProfiles(query){
+ return getCall("/user/search", query ? {query} : {}).then((data)=>{
+ if(data.status == "ok"){
+ data.profiles.forEach((p)=>{
+ userNameCache[p._id] = p;
+ });
+ return data
+ }
+ });
+ },
+ changeProfile(profileid){
+ return postCall("/changeProfile", {profileid}).then((profile) =>{
+ CurrentProfile = profileid;
+ CurrentProfileData = profile;
+ return profile;
+ });
+ },
+ getUserProfile(profileid, refresh=false) {
+ return getProfileFromCache(profileid, refresh);
+ },
+ currentProfileId() {
+ if (!CurrentProfile) this.isLoggedIn(); //replace with cookie
+ return CurrentProfile;
+ },
+ followProfile(profileid){
+ return getCall("/user/" + profileid + "/follow");
+ },
+ unfollowProfile(profileid){
+ return getCall("/user/" + profileid + "/unfollow");
+ },
+ setDataValue(key, value){
+ return postCall("/user/setData", {key, value});
+ },
+ //Groups
+ newGroup(title, subtitle, description, isPrivate=false, isCourse=false) {
+ return postCall("/user/groups", {
+ profile: {
+ firstName: title,
+ lastName: subtitle,
+ description
+ },
+ isPrivate,
+ isCourse
+ });
+ },
+ getRecentGroups() {
+ return getCall("/user/groups");
+ },
+ searchGroups(query){
+ return getCall("/user/groups/search", query ? {query} : {}).then((data)=>{
+ if(data.status == "ok"){
+ data.groups.forEach((p)=>{
+ userNameCache[p._id] = p;
+ });
+ return data
+ }
+ });
+ },
+ getCourses() {
+ return getCall("/user/courses");
+ },
+ searchCourses(query){
+ return getCall("/user/groups/search", query ? {query, courses: true} : {courses: true}).then((data)=>{
+ if(data.status == "ok"){
+ data.groups.forEach((p)=>{
+ userNameCache[p._id] = p;
+ });
+ return data
+ }
+ });
+ },
+ getGroup(groupid) {
+ return getCall("/user/groups/" + groupid);
+ },
+ subscribeToGroup(groupid){
+ return getCall("/user/groups/" + groupid + "/subscribe");
+ },
+ acceptGroupRequest(profileid, groupid){
+ return postCall("/user/groups/accept", {profileid, groupid});
+ },
+ rejectGroupRequest(profileid, groupid){
+ return postCall("/user/groups/reject", {profileid, groupid});
+ },
+ unsubscribeToGroup(groupid){
+ return getCall("/user/groups/" + groupid + "/unsubscribe");
+ }
+}
+
+export default API;
\ No newline at end of file
diff --git a/App.js b/App.js
index 181f3ce..882ef8a 100644
--- a/App.js
+++ b/App.js
@@ -1,21 +1,33 @@
import { StatusBar } from 'expo-status-bar';
-import React from 'react';
-import { StyleSheet, Text, View } from 'react-native';
+import React, { useEffect, useState } from 'react';
+import { StyleSheet, Text, View, TextInput } from 'react-native';
+import API from './API.js';
+import LoginForm from './components/Login.js';
+import Feed from './components/Feed.js';
export default function App() {
- return (
-
- Open up App.js to start working on your app!
-
-
- );
+ let [isLoggedIn, setIsLoggedIn] = useState(false);
+
+ useEffect(async () => {
+ let r = await API.isLoggedIn();
+ setIsLoggedIn(r);
+ }, []);
+
+ return (
+
+ EMI Social LOGO
+ {!isLoggedIn && }
+ {isLoggedIn && }
+
+
+ );
}
const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
+ container: {
+ flex: 1,
+ backgroundColor: '#fff',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
});
diff --git a/components/Feed.js b/components/Feed.js
new file mode 100644
index 0000000..3d7af95
--- /dev/null
+++ b/components/Feed.js
@@ -0,0 +1,34 @@
+import { StatusBar } from 'expo-status-bar';
+import React, { useState, useEffect } from 'react';
+import { Text, View, ScrollView, Button } from 'react-native';
+import API from './../API.js';
+
+
+let Feed = () => {
+ let [Me, setMeProfile] = useState({});
+ let [Posts, setPosts] = useState([]);
+ useEffect(async () => {
+ let r = await API.getMe();
+ setMeProfile(r);
+ let posts = await API.getPosts();
+ setPosts(posts)
+ //console.log(posts)
+ }, []);
+
+ return (
+
+
+ Hello: {Me.profile && Me.profile.firstName} {Me.profile && Me.profile.lastName}
+ {
+ Posts.map((post, i) => {
+ return (
+ {post.content}
+ )
+ })
+ }
+
+
+ );
+}
+
+export default Feed;
diff --git a/components/Login.js b/components/Login.js
new file mode 100644
index 0000000..a088e00
--- /dev/null
+++ b/components/Login.js
@@ -0,0 +1,49 @@
+import { StatusBar } from 'expo-status-bar';
+import React, { useState } from 'react';
+import { Text, View, TextInput, Button } from 'react-native';
+import API from './../API.js';
+
+
+let LoginForm = ()=>{
+ let [email, setEmail] = useState('');
+ let [password, setPassword] = useState('');
+
+ return (
+
+ Log in
+ setEmail(text)}
+ defaultValue={email}
+ placeholder=" email"
+ />
+ setPassword(text)}
+ defaultValue={password}
+ placeholder=" password"
+ textContentType="password"
+ secureTextEntry={true}
+ />
+
+ );
+}
+
+export default LoginForm;