add ability to post statuses
This commit is contained in:
		
							parent
							
								
									525066e6ea
								
							
						
					
					
						commit
						4220e61042
					
				
					 5 changed files with 108 additions and 4 deletions
				
			
		|  | @ -1,4 +1,8 @@ | |||
| import { database } from '../_database/database' | ||||
| import { store } from '../_store/store' | ||||
| import { toast } from '../_utils/toast' | ||||
| import { postStatus as postStatusToServer } from '../_api/statuses' | ||||
| import { addStatusOrNotification } from './addStatusOrNotification' | ||||
| 
 | ||||
| export async function getIdThatThisStatusReblogged (instanceName, statusId) { | ||||
|   let status = await database.getStatus(instanceName, statusId) | ||||
|  | @ -19,3 +23,27 @@ export async function getIdsThatRebloggedThisStatus (instanceName, statusId) { | |||
| export async function getNotificationIdsForStatuses (instanceName, statusIds) { | ||||
|   return database.getNotificationIdsForStatuses(instanceName, statusIds) | ||||
| } | ||||
| 
 | ||||
| export async function postStatus(realm, text, inReplyToId, mediaIds, | ||||
|                                  sensitive, spoilerText, visibility) { | ||||
|   let instanceName = store.get('currentInstance') | ||||
|   let accessToken = store.get('accessToken') | ||||
|   let online = store.get('online') | ||||
| 
 | ||||
|   if (!online) { | ||||
|     toast.say('You cannot post while offline') | ||||
|     return | ||||
|   } | ||||
| 
 | ||||
|   store.set({postingStatus: true}) | ||||
|   try { | ||||
|     let status = await postStatusToServer(instanceName, accessToken, text, | ||||
|       inReplyToId, mediaIds, sensitive, spoilerText, visibility) | ||||
|     addStatusOrNotification(instanceName, 'home', status) | ||||
|     store.clearComposeData(realm) | ||||
|   } catch (e) { | ||||
|     toast.say('Unable to post status: ' + (e.message || '')) | ||||
|   } finally { | ||||
|     store.set({postingStatus: false}) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										25
									
								
								routes/_api/statuses.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								routes/_api/statuses.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| import { auth, basename } from './utils' | ||||
| import { postWithTimeout } from '../_utils/ajax' | ||||
| 
 | ||||
| export async function postStatus(instanceName, accessToken, text, inReplyToId, mediaIds, | ||||
|                                  sensitive, spoilerText, visibility) { | ||||
|   let url = `${basename(instanceName)}/api/v1/statuses` | ||||
| 
 | ||||
|   let body = { | ||||
|     status: text, | ||||
|     in_reply_to_id: inReplyToId, | ||||
|     media_ids: mediaIds, | ||||
|     sensitive: sensitive, | ||||
|     spoiler_text: spoilerText, | ||||
|     visibility: visibility | ||||
|   } | ||||
| 
 | ||||
|   for (let key of Object.keys(body)) { | ||||
|     let value = body[key] | ||||
|     if (!value || (Array.isArray(value) && !value.length)) { | ||||
|       delete body[key] | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return postWithTimeout(url, body, auth(accessToken)) | ||||
| } | ||||
|  | @ -11,7 +11,7 @@ | |||
|   <ComposeToolbar :realm :postPrivacy :media :contentWarningShown /> | ||||
|   <ComposeLengthIndicator :length :overLimit /> | ||||
|   <ComposeMedia :realm :media /> | ||||
|   <ComposeButton :length :overLimit /> | ||||
|   <ComposeButton :length :overLimit on:click="onClickPostButton()" /> | ||||
| </div> | ||||
| <style> | ||||
|   .compose-box { | ||||
|  | @ -58,6 +58,7 @@ | |||
|   import { CHAR_LIMIT, POST_PRIVACY_OPTIONS } from '../../_static/statuses' | ||||
|   import { store } from '../../_store/store' | ||||
|   import { slide } from 'svelte-transitions' | ||||
|   import { postStatus } from '../../_actions/statuses' | ||||
| 
 | ||||
|   export default { | ||||
|     components: { | ||||
|  | @ -89,6 +90,20 @@ | |||
|     }, | ||||
|     transitions: { | ||||
|       slide | ||||
|     }, | ||||
|     methods: { | ||||
|       onClickPostButton() { | ||||
|         let text = this.get('text') | ||||
|         let media = this.get('media') | ||||
|         let postPrivacyKey = this.get('postPrivacyKey') | ||||
|         let contentWarning = this.get('contentWarning') | ||||
|         let sensitive = media.length && !!contentWarning | ||||
|         let realm = this.get('realm') | ||||
|         let mediaIds = media.map(_ => _.data.id) | ||||
| 
 | ||||
|         /* no await */ postStatus(realm, text, null, mediaIds, | ||||
|           sensitive, contentWarning, postPrivacyKey) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,6 +1,15 @@ | |||
| <button class="primary compose-box-button" | ||||
|         :disabled > | ||||
|   Toot! | ||||
|         :disabled | ||||
|         on:click> | ||||
|   <span class="{{$postingStatus ? 'hidden' : ''}}"> | ||||
|     Toot! | ||||
|   </span> | ||||
|   <div class="compose-box-button-spinner {{$postingStatus ? 'spin' : 'hidden'}}" | ||||
|        aria-hidden="true"> | ||||
|     <svg> | ||||
|       <use xlink:href="#fa-spinner" /> | ||||
|     </svg> | ||||
|   </div> | ||||
| </button> | ||||
| <style> | ||||
|   .compose-box-button { | ||||
|  | @ -8,6 +17,24 @@ | |||
|     justify-self: right; | ||||
|     text-transform: uppercase; | ||||
|     margin-top: 10px; | ||||
|     position: relative; | ||||
|   } | ||||
|   .compose-box-button-spinner { | ||||
|     pointer-events: none; | ||||
|     position: absolute; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     z-index: 10; | ||||
|     top: 0; | ||||
|     bottom: 0; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
|   } | ||||
|   .compose-box-button-spinner svg { | ||||
|     width: 24px; | ||||
|     height: 24px; | ||||
|     fill: var(--button-primary-text); | ||||
|   } | ||||
| </style> | ||||
| <script> | ||||
|  | @ -16,7 +43,7 @@ | |||
|   export default { | ||||
|     store: () => store, | ||||
|     computed: { | ||||
|       disabled: (overLimit, length) => overLimit || length === 0 | ||||
|       disabled: ($postingStatus, overLimit, length) => $postingStatus || overLimit || length === 0 | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | @ -14,4 +14,13 @@ export function instanceMixins (Store) { | |||
|       composeData[instanceName][realm] && | ||||
|       composeData[instanceName][realm][key] | ||||
|   } | ||||
| 
 | ||||
|   Store.prototype.clearComposeData = function (realm) { | ||||
|     let composeData = this.get('composeData') | ||||
|     let instanceName = this.get('currentInstance') | ||||
|     if (composeData && composeData[instanceName]) { | ||||
|       delete composeData[instanceName][realm] | ||||
|     } | ||||
|     this.set({composeData}) | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue