Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Working on stability of photo uploads.

  • Loading branch information...
commit 77c3fa59964f7549f309a55c366decc0e175db30 1 parent 46d39d8
@jubishop authored
View
10 fbair.mxml
@@ -172,8 +172,8 @@
else if (FBConnect.status == FBConnect.NotLoggedIn) {
requiredSession = true;
requiredPermissions = false;
- FBConnect.requireSession(
- {"req_perms":"read_stream,publish_stream,read_mailbox"});
+ FBConnect.requireSession({"req_perms":
+ "read_stream,publish_stream,read_mailbox,offline_access"});
}
}
@@ -188,7 +188,8 @@
private function permissionChanged(event:FBEvent = null):void {
if (FBConnect.hasPermission("read_stream") &&
FBConnect.hasPermission("publish_stream") &&
- FBConnect.hasPermission("read_mailbox"))
+ FBConnect.hasPermission("read_mailbox") &&
+ FBConnect.hasPermission("offline_access"))
fullyAuthorized();
else if (requiredPermissions)
close();
@@ -197,7 +198,8 @@
requiredPermissions = true;
FBConnect.requirePermissions(["read_stream",
"publish_stream",
- "read_mailbox"]);
+ "read_mailbox",
+ "offline_access"]);
}
}
View
97 fbair/composer/Composer.mxml
@@ -17,6 +17,7 @@
Major container for letting the user share stuff! -->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:util="fbair.util.display.*"
+ xmlns:composer="fbair.composer.*"
verticalGap="5">
<mx:Metadata>
[Event(name="statusUpdated", type="fb.FBEvent")]
@@ -25,7 +26,7 @@
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:util="fbair.util.display.*"
width="100%"
- verticalGap="4">
+ horizontalGap="6">
<!-- Text area for entering your status update -->
<util:GrowableTextArea id="composerInput"
@@ -61,14 +62,14 @@
styleName="albumFieldText" />
</mx:HBox>
- <mx:TileList id="droppedPhotoList"
- width="100%"
- dataProvider="{droppedPhotos}"
- includeInLayout="false"
- visible="false"
- styleName="droppedPhotoList"
- creationComplete="photoListCreationComplete(event)"
- itemRenderer="fbair.composer.DroppedPhotosRenderer" />
+ <composer:DroppedPhotosList id="droppedPhotoList"
+ width="100%"
+ dataProvider="{droppedPhotos}"
+ visible="false"
+ styleName="droppedPhotoList"
+ nativeDragEnter="dragEnter(event)"
+ nativeDragDrop="dragDrop(event)"
+ creationComplete="photoCreationComplete(event)" />
<mx:Script><![CDATA[
import fb.FBAPI;
@@ -95,6 +96,14 @@
import mx.events.FlexEvent;
import mx.utils.ObjectProxy;
+ private static const ValidPhotoTypes:Array = [
+ "jpg",
+ "jpeg",
+ "gif",
+ "png",
+ "bmp"
+ ];
+
private var submittedMessage:String;
[Bindable]
@@ -106,6 +115,7 @@
private static const FOCUS_OUT_STATUS:String = "What's on your mind?";
private static const FOCUS_OUT_CAPTION:String = "Describe your photo";
+ private static const FOCUS_OUT_ALBUM:String = "Describe your album";
private static const APP_DEFAULT_ALBUM_NAME:String =
"Facebook for Adobe AIR Photos";
@@ -114,7 +124,7 @@
"http://www.facebook.com/editphoto.php?aid=";
// Called when the composer is initialized
- private function photoListCreationComplete(event:FlexEvent):void {
+ private function photoCreationComplete(event:FlexEvent):void {
droppedPhotoList.addEventListener(FBEvent.DELETED, deletePhoto);
}
@@ -240,16 +250,6 @@
resetFields();
}
- // This just resets things to start
- private function resetFields():void {
- submittedMessage = null;
- composerInput.text = composerInput.focusOutText;
- composerInput.editable = true;
- shareButton.enabled = true;
- FBConnect.dispatcher.dispatchEvent(new FBEvent(FBEvent.ENABLE));
- hidePhotosPanel();
- }
-
/**
* Called when a photo in a single-photo upload operation succeeeds
*/
@@ -308,8 +308,20 @@
var files:Array = event.clipboard.getData(
ClipboardFormats.FILE_LIST_FORMAT) as Array;
+ // Inline functions are hot.
+ var hasPhoto:Function = function(url:String):Boolean {
+ for (var i:int = 0; i < droppedPhotos.length; i++)
+ if (droppedPhotos.getItemAt(i).source == url) return true;
+ return false;
+ }
+ var previousNumberOfPhotos:int = droppedPhotos.length;
+
for each (var photo:File in files) {
+ // Don't add dupes or invalid file types
+ if (hasPhoto(photo.url)) continue;
+ if (ValidPhotoTypes.indexOf(photo.extension) == -1) continue;
+
photo.load();
droppedPhotos.addItem(new ObjectProxy({
file: photo,
@@ -317,13 +329,13 @@
}));
}
- // Make the dropped photo list appear
- droppedPhotoList.includeInLayout = true;
+ // If we didn't add any photos, then fuck it.
+ if (droppedPhotos.length == previousNumberOfPhotos) return;
+
droppedPhotoList.visible = true;
composerInput.focusOutText = FOCUS_OUT_CAPTION;
-
if (droppedPhotos.length > 1) {
- composerInput.focusOutText += 's';
+ composerInput.focusOutText = FOCUS_OUT_ALBUM;
albumName.visible = true;
albumName.includeInLayout = true;
}
@@ -331,23 +343,42 @@
// Called when the delete button is pressed on a photo
private function deletePhoto(event:FBEvent):void {
- if (droppedPhotoList.selectedIndex > -1) {
- droppedPhotos.removeItemAt(droppedPhotoList.selectedIndex);
+ droppedPhotos.removeItemAt(droppedPhotos.getItemIndex(event.target.data));
+
+ if (droppedPhotos.length == 1) {
+ resetAlbumField();
+ composerInput.focusOutText = FOCUS_OUT_CAPTION;
}
-
- if (droppedPhotos.length == 0) hidePhotosPanel();
+
+ if (droppedPhotos.length == 0) resetPhotosPanel();
}
/**
- * Called after the photo grid has finished disappearing
+ * Reset composer fields
*/
- private function hidePhotosPanel():void {
- droppedPhotoList.includeInLayout = false;
- droppedPhotoList.visible = false;
+ private function resetFields():void {
+ resetPhotosPanel();
+ submittedMessage = null;
+ composerInput.editable = true;
+ shareButton.enabled = true;
+ FBConnect.dispatcher.dispatchEvent(new FBEvent(FBEvent.ENABLE));
+ }
+
+ /**
+ * Hide album field
+ */
+ private function resetAlbumField():void {
albumName.visible = false;
albumName.includeInLayout = false;
albumNameInput.text = '';
- composerInput.text = composerInput.focusOutText;
+ }
+
+ /**
+ * Hide all photo stuff.
+ */
+ private function resetPhotosPanel():void {
+ resetAlbumField();
+ droppedPhotoList.visible = false;
composerInput.focusOutText = FOCUS_OUT_STATUS;
}
]]></mx:Script>
View
88 fbair/composer/DroppedPhotosList.mxml
@@ -0,0 +1,88 @@
+<!--
+ Copyright Facebook Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<!-- Loading indicator displays itself when we have trouble connecting
+ to Facebook for authentication or stream loading -->
+<util:AnimatedCanvas xmlns:mx="http://www.adobe.com/2006/mxml"
+ xmlns:util="fbair.util.display.*"
+ animateOut="true" >
+ <mx:Script><![CDATA[
+ import fb.util.Output;
+
+ import fbair.composer.DroppedPhotosRenderer;
+ import fbair.gc.Depot;
+
+ import mx.collections.ArrayCollection;
+ import mx.events.CollectionEvent;
+
+ private static const ITEM_PADDING:int = 6;
+
+ private var _dataProvider:ArrayCollection;
+
+ private var renderers:Array = new Array();
+
+ public function get dataProvider():ArrayCollection {
+ return _dataProvider;
+ }
+
+ public function set dataProvider(newProvider:ArrayCollection):void {
+ if (dataProvider)
+ dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
+ collectionChange);
+
+ _dataProvider = newProvider;
+ dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,
+ collectionChange);
+
+ invalidateDisplayList();
+ }
+
+ private function collectionChange(event:CollectionEvent):void {
+ invalidateDisplayList();
+ }
+
+ override protected function updateDisplayList(unscaledWidth:Number,
+ unscaledHeight:Number):void {
+
+ while(renderers.length > dataProvider.length) {
+ var deadRenderer:DroppedPhotosRenderer = renderers.pop();
+ removeChild(deadRenderer);
+ Depot.put(deadRenderer);
+ }
+
+ while (renderers.length < dataProvider.length) {
+ var newRenderer:DroppedPhotosRenderer =
+ Depot.get(DroppedPhotosRenderer);
+ renderers.push(newRenderer);
+ addChild(newRenderer);
+ }
+
+ if (! dataProvider || dataProvider.length == 0) return;
+
+ var columns:int = 1;
+ columns += Math.floor(
+ (unscaledWidth - DroppedPhotosRenderer.MAX_DIMENSION) /
+ (DroppedPhotosRenderer.MAX_DIMENSION + ITEM_PADDING));
+
+ for (var i:int = 0; i < dataProvider.length; i++) {
+ renderers[i].data = dataProvider.getItemAt(i);
+ renderers[i].x = ((i % columns) *
+ (DroppedPhotosRenderer.MAX_DIMENSION + ITEM_PADDING));
+ renderers[i].y = (Math.floor(i / columns) *
+ (DroppedPhotosRenderer.MAX_DIMENSION + ITEM_PADDING));
+ }
+ }
+ ]]></mx:Script>
+</util:AnimatedCanvas>
View
29 fbair/composer/DroppedPhotosRenderer.mxml
@@ -13,14 +13,39 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
+<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
+ width="{MAX_DIMENSION}"
+ height="{MAX_DIMENSION}" >
+
<mx:Image id="photo"
source="{data.source}"
- left="5" />
+ complete="imageLoadComplete(event)" />
+
<mx:Button id="closeButton"
styleName="storyDeleteButton"
+ left="2"
+ top="2"
click="dispatchEvent(new FBEvent(FBEvent.DELETED))" />
+
<mx:Script><![CDATA[
import fb.FBEvent;
+
+ import flash.events.Event;
+
+ public static const MAX_DIMENSION:int = 112;
+
+ private function imageLoadComplete(event:Event):void {
+ var aspectRatio:Number = photo.contentWidth / photo.contentHeight;
+ if (aspectRatio > 1) {
+ photo.width = MAX_DIMENSION;
+ photo.height = photo.width / aspectRatio;
+ }
+ else {
+ photo.height = MAX_DIMENSION;
+ photo.width = photo.height * aspectRatio;
+ }
+ photo.y = (MAX_DIMENSION - photo.height) / 2;
+ photo.x = (MAX_DIMENSION - photo.width) / 2;
+ }
]]></mx:Script>
</mx:Canvas>
Please sign in to comment.
Something went wrong with that request. Please try again.