diff --git a/package-lock.json b/package-lock.json
index a26919a..21ab0a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@react-navigation/native": "5.1.1",
"@react-navigation/stack": "5.2.3",
"expo": "^38.0.9",
+ "expo-image-picker": "~8.3.0",
"expo-linking": "^1.0.7",
"expo-status-bar": "^1.0.2",
"expo-web-browser": "~8.3.1",
@@ -3608,6 +3609,23 @@
"fontfaceobserver": "^2.1.0"
}
},
+ "node_modules/expo-image-picker": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-8.3.0.tgz",
+ "integrity": "sha512-HCF7SumPE4jXH+EhJ19Xw6G8Lxpms1z6Hxdq/kLlzvZGdzH4ZFBqp3NyTO7dtm0dXtjduljpNK7kQfwWtvmIWQ==",
+ "dependencies": {
+ "expo-permissions": "~9.0.1",
+ "uuid": "7.0.2"
+ }
+ },
+ "node_modules/expo-image-picker/node_modules/uuid": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz",
+ "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/expo-keep-awake": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-8.2.1.tgz",
@@ -12340,6 +12358,22 @@
"fontfaceobserver": "^2.1.0"
}
},
+ "expo-image-picker": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-8.3.0.tgz",
+ "integrity": "sha512-HCF7SumPE4jXH+EhJ19Xw6G8Lxpms1z6Hxdq/kLlzvZGdzH4ZFBqp3NyTO7dtm0dXtjduljpNK7kQfwWtvmIWQ==",
+ "requires": {
+ "expo-permissions": "~9.0.1",
+ "uuid": "7.0.2"
+ },
+ "dependencies": {
+ "uuid": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz",
+ "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw=="
+ }
+ }
+ },
"expo-keep-awake": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-8.2.1.tgz",
diff --git a/package.json b/package.json
index ede1137..18024b2 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"@react-navigation/native": "5.1.1",
"@react-navigation/stack": "5.2.3",
"expo": "^38.0.9",
+ "expo-image-picker": "~8.3.0",
"expo-linking": "^1.0.7",
"expo-status-bar": "^1.0.2",
"expo-web-browser": "~8.3.1",
diff --git a/src/components/pages/profile/settings.js b/src/components/pages/profile/settings.js
index 1c57648..34ea97d 100644
--- a/src/components/pages/profile/settings.js
+++ b/src/components/pages/profile/settings.js
@@ -9,49 +9,22 @@ import {
TouchableOpacity,
Dimensions,
} from "react-native";
+import { FontAwesome } from '@expo/vector-icons';
import AsyncStorage from "@react-native-async-storage/async-storage";
+import * as requests from "src/requests";
+
+import * as ImagePicker from 'expo-image-picker';
import { withoutHTML } from "src/interface/rendering";
-import * as requests from "src/requests";
import { ScreenWithBackBarJsx } from "src/components/navigation/navigators";
-const TEST_IMAGE = "https://cache.desktopnexus.com/thumbseg/2255/2255124-bigthumbnail.jpg";
-const TEST_PROFILE = {
- username: "njms",
- acct: "njms",
- display_name: "Nat🔆",
- locked: false,
- bot: false,
- note: "Yeah heart emoji.",
- avatar: TEST_IMAGE,
- followers_count: "1 jillion",
- statuses_count: 334,
- fields: [
- {
- name: "Blog",
- value: "https://njms.ca",
- verified_at: "some time"
- },
- {
- name: "Github",
- value: "https://github.com/natjms",
- verified_at: null
- }
- ]
-};
-
const SettingsJsx = (props) => {
const [state, setState] = useState({
- // Use Context to get this stuff eventually
- profile: TEST_PROFILE,
- newProfile: TEST_PROFILE,
loaded: false,
});
- const fields = state.newProfile.fields;
-
const _handleLogout = async () => {
await requests.postForm(
`https://${state.instance}/oauth/revoke`,
@@ -96,24 +69,76 @@ const SettingsJsx = (props) => {
setState({...state,
profile: profile,
- newProfile: newProfile,
instance: instance,
appObject: appObject,
- token: token,
+ accessToken: token.access_token,
+
+ // Malleable props that will actually go towards updating
+ // the profile credentials
+ locked: profile.locked,
+ newAvatar: {
+ uri: profile.avatar,
+ },
+ display_name: profile.display_name,
+ note: profile.note,
+
loaded: true,
})
});
}, []);
+ const _handleChangeProfilePhoto = async () => {
+ await ImagePicker.getCameraRollPermissionsAsync()
+
+ const { base64, uri } = await ImagePicker.launchImageLibraryAsync({
+ allowsEditing: true,
+ aspect: [1, 1],
+ });
+
+ setState({...state,
+ newAvatar: {
+ base64,
+ uri,
+ },
+ });
+ };
+
+ const _handleSaveProfile = async () => {
+ let params = {
+ display_name: state.display_name,
+ note: state.note,
+ locked: state.locked,
+ };
+ if (state.newAvatar.base64) {
+ let blob = fetch(state.newAvatar.base64).then(res => res.blob());
+ let filename = uri.split("/")[uri.split("/").length - 1];
+
+ params.avatar = new File([blob], filename);
+ }
+
+ const newProfile = await fetch(
+ `https://${state.instance}/api/v1/accounts/update_credentials`,
+ {
+ method: "PATCH",
+ body: requests.objectToForm(params),
+ headers: { "Authorization": `Bearer ${state.accessToken}`, }
+ }
+ ).then(resp => resp.json());
+
+ await AsyncStorage.setItem("@user_profile", JSON.stringify(newProfile));
+
+ props.navigation.navigate("Profile");
+ };
+
return (
<>
{ state.loaded
?
-
+
Change profile photo
@@ -124,24 +149,11 @@ const SettingsJsx = (props) => {
{
setState({...state,
- newProfile: {...state.newProfile, display_name: value}
- });
- }
- }/>
-
- User name
- {
- setState({...state,
- newProfile: {...state.newProfile, username: value}
+ display_name: value,
});
}
}/>
@@ -156,110 +168,40 @@ const SettingsJsx = (props) => {
}
multiline = { true }
placeholder = { "Bio" }
- value = { withoutHTML(state.newProfile.note) }
+ // HACK: Using withoutHTML here is dangerous
+ value = { withoutHTML(state.note) }
onChangeText = {
(value) => {
setState({...state,
- newProfile: {...state.newProfile, note: value}
+ note: value
});
}
}/>
- {
- fields.map((field, i) =>
-
- {
- let newFields;
- if (fields.length == 1) {
- newFields = [{ name: "", value: "" }];
- } else {
- newFields = state.newProfile.fields;
- newFields.splice(i, 1);
- }
- setState({...state,
- newProfile: {...state.newProfile,
- fields: newFields,
- },
- });
- }
- }>
-
-
-
- Name
- {
- let newFields = fields;
- newFields[i] = {...newFields[i],
- name: text,
- };
-
- setState({...state,
- newProfile: {...state.newProfile,
- fields: newFields,
- },
- });
- }
- } />
-
-
- Value
- {
- let newFields = fields;
- newFields[i] = {...newFields[i],
- value: text,
- };
-
- setState({...state,
- newProfile: {...state.newProfile,
- fields: newFields,
- },
- });
- }
- } />
-
-
- )
- }
{
+ () => (
setState({...state,
- newProfile: {...state.newProfile,
- fields: state.newProfile.fields.concat({ name: "", value: ""}),
- },
- });
- }
+ locked: !state.locked
+ })
+ )
}>
-
+
+ <>
+ { !state.locked
+ ?
+ :
+ }
+ >
+
+ Manually approve follow requests?
+
+
-
+
+
Save Profile