Skip to content

Instantly share code, notes, and snippets.

@carsonfarmer
Last active April 4, 2019 00:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carsonfarmer/26a0e1936aef22006cfef7fdc1bad8d6 to your computer and use it in GitHub Desktop.
Save carsonfarmer/26a0e1936aef22006cfef7fdc1bad8d6 to your computer and use it in GitHub Desktop.
Full 'app' diff
diff --git a/src/Main.js b/src/Main.js
index a545559..e34f915 100644
--- a/src/Main.js
+++ b/src/Main.js
@@ -1,21 +1,11 @@
import React, { Component } from 'react'
import { observer, inject } from 'mobx-react'
-import { Image } from 'semantic-ui-react'
-// import Moment from 'react-moment'
-import * as Logo from './LaunchLogo@3x.png'
+import Profile from './Profile'
@inject('store') @observer
class Main extends Component {
- render() {
- const { store } = this.props
- return (
- <div>
- <Image centered size='medium' src={Logo} />
- <p>
- {store.profile.address}
- </p>
- </div>
- )
+ render () {
+ return <Profile />
}
}
diff --git a/src/Store.js b/src/Store.js
index b73cdcb..94dd688 100644
--- a/src/Store.js
+++ b/src/Store.js
@@ -1,7 +1,10 @@
-import { observe, action, observable } from 'mobx'
+import { observe, action, observable, runInAction } from 'mobx'
+import { utc } from 'moment'
import { Textile } from '@textileio/js-http-client'
import { toast } from 'react-semantic-toasts'
+const THREAD_KEY = 'avatarThreadKey'
+
const textile = new Textile({
url: 'http://127.0.0.1',
port: 40602
@@ -40,6 +43,47 @@ class Store {
})
})
}
+ @action async setProfile(userString, avatarFile) {
+ if (userString) {
+ textile.profile.setUsername(userString).then(() => {
+ runInAction('setUsername', () => {
+ this.profile.name = userString
+ this.profile.updated = utc().format()
+ })
+ })
+ }
+ if (avatarFile) {
+ let avatarThread
+ const threads = await textile.threads.list()
+ for (const thread of threads.items) {
+ if (thread.key === THREAD_KEY) {
+ avatarThread = thread
+ break
+ }
+ }
+ if (!avatarThread) {
+ const schemas = await textile.schemas.defaults()
+ const avatarSchema = schemas.avatar
+ const file = await textile.schemas.add(avatarSchema)
+ avatarThread = await textile.threads.add(
+ 'avatars',
+ file.hash,
+ THREAD_KEY,
+ 'public',
+ 'notshared'
+ )
+ }
+ const addedFile = await textile.files.addFile(avatarFile, 'avatar', avatarThread.id)
+ await textile.profile.setAvatar(addedFile.files[0].links.large.hash)
+ runInAction('setAvatar', () => {
+ this.profile.avatar = addedFile.target
+ this.profile.updated = utc().format()
+ })
+ }
+ toast({
+ title: 'Profile updated',
+ description: 'Your profile has been updated!'
+ })
+ }
}
export default Store
import React, { Component } from 'react'
import { observer, inject } from 'mobx-react'
import { Card, Icon, Image, Input, Form } from 'semantic-ui-react'
import Moment from 'react-moment'
@inject('store') @observer
class Profile extends Component {
handleUsername = e => {
e.preventDefault()
this.props.store.setProfile(this.inputRef.value, null)
}
handleAvatar = e => {
e.preventDefault()
const file = e.target.files[0]
const form = new FormData();
form.append("file", file, file.name);
this.props.store.setProfile(null, form)
}
render () {
const { gateway, profile } = this.props.store
return (
<div>
<Card style={{ width: '100%' }}>
<Card.Content>
<div style={{ textAlign: 'center' }}>
<input
type="file"
id="file"
ref="fileUploader"
style={{ display: "none" }}
onChange={this.handleAvatar}
/>
<Image
as='a'
size='medium'
circular
src={
profile.avatar ?
`${gateway}/ipfs/${profile.avatar}/0/large/d` :
'https://react.semantic-ui.com/images/wireframe/square-image.png'
}
onClick={() => { this.refs.fileUploader.click() }}
style={{ minHeight: '250px' }}
/>
</div>
<Card.Header style={{ paddingTop: '1em'}}>
<Form onSubmit={this.handleUsername}>
<Form.Field>
<Input iconPosition='left' defaultValue={profile.name}>
<Icon name='user' />
<input ref={c => { this.inputRef = c }} />
</Input>
</Form.Field>
</Form>
</Card.Header>
<Card.Description>
<p title='peer id'>
<Icon name='user secret' />{profile.id}
</p>
<p title='address'>
<Icon name='linkify' />{profile.address}
</p>
</Card.Description>
</Card.Content>
<Card.Content extra>
Updated <Moment fromNow>{profile.updated}</Moment>
</Card.Content>
</Card>
</div>
)
}
}
export default Profile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment