Ongoing work on conversations and display issues
This commit is contained in:
parent
18c5597ed9
commit
f0eda65a63
@ -1 +1 @@
|
||||
package com.sqwiggle {
import com.sqwiggle.Member;
import com.sqwiggle.Self;
import com.sqwiggle.GUID;
import flash.utils.Dictionary;
public class Conversation extends Object {
public var id:String;
private var length:Number;
public var members:Object;
public function Conversation() {
this.members = new Object();
}
public function addMember(member:Member, inConversation:Boolean=false):void {
trace('Conversation:addMember', member.userId);
members[member.userId] = member;
member.audioOn(inConversation);
length++;
}
public function removeMember(member:Member, inConversation:Boolean=false):void {
trace('Conversation:removeMember', member.userId);
delete members[member.userId];
member.audioOff(inConversation);
length--;
}
public function hasMember(member:Member):Boolean {
return !!members[member.userId];
}
public function isEmpty():Boolean {
return length == 1;
}
}
}
|
||||
package com.sqwiggle {
import com.sqwiggle.Member;
import com.sqwiggle.Self;
import com.sqwiggle.GUID;
import flash.utils.Dictionary;
public class Conversation extends Object {
public var id:String;
private var length:Number;
public var members:Object;
public function Conversation() {
this.members = new Object();
}
public function removeAllMembers():void {
for (var i in members) {
removeMember(members[i], false);
}
}
public function addMember(member:Member, inConversation:Boolean=false):void {
trace('Conversation:addMember', member.userId);
members[member.userId] = member;
member.audioOn(inConversation);
length++;
}
public function removeMember(member:Member, inConversation:Boolean=false):void {
trace('Conversation:removeMember', member.userId);
delete members[member.userId];
member.audioOff(inConversation);
length--;
}
public function hasMember(member:Member):Boolean {
return !!members[member.userId];
}
public function isEmpty():Boolean {
return length == 1;
}
}
}
|
@ -1 +1 @@
|
||||
package com.sqwiggle {
import com.sqwiggle.Conversation;
import com.sqwiggle.Self;
import com.sqwiggle.events.ApiEvent;
import flash.events.Event;
import flash.net.URLLoader;
import flash.events.EventDispatcher;
public class Conversations extends EventDispatcher {
private var ongoing:Object;
private var colours:Array;
private var self:Self;
public var members:Object;
public function Conversations(self:Self, members:Object) {
this.ongoing = new Object();
this.members = members;
this.self = self;
// make an API request to get ongoing conversations
var request = Api.getRequest('/conversations');
request.addEventListener(Event.COMPLETE, function(event:ApiEvent) {
updateMembers(event.data.conversations);
});
}
public function updateMembers(conversations:Object):void {
// first find if the current user is in any conversation
var selfInConversation = false;
for (var a in conversations) {
for (var b in conversations[a].users) {
if (conversations[a].users[b].id == self.userId) {
selfInConversation = a;
}
}
}
for (var i in conversations) {
trace('updating conversation', i);
// we dont know about this conversation
if (!ongoing[i]) {
ongoing[i] = new Conversation();
ongoing[i].id = i;
}
var conversation = ongoing[i];
var existingMembers = conversation.members;
var selfInCurrentConversation = selfInConversation == i;
// find existing members that should leave the convo
for (var j in existingMembers) {
// check if this user is still in the convo
var filter = conversations[i].users.filter(function(user){ return user.id == this.userId; }, existingMembers[j]);
var inConversation = !!filter.length;
if (!inConversation) {
trace('removing member from conversation', member.userId, conversation.id);
conversation.removeMember(member, selfInCurrentConversation);
}
}
// for every user that should be in this conversation
for (var k in conversations[i].users) {
var user = conversations[i].users[k];
var member;
if (user.id == self.userId) {
member = self;
} else {
member = members[user.id];
}
if (!member) {
continue;
}
if (!conversation.hasMember(member)) {
if (selfInCurrentConversation) {
trace('member already in a conversation with you');
} else {
trace('adding member to conversation', member.userId, conversation.id);
}
conversation.addMember(member, selfInCurrentConversation);
}
}
}
dispatchEvent(new Event("conversationsupdated"));
}
public function getConversationForMember(member:Member):Conversation {
for (var i in ongoing) {
if (ongoing[i].hasMember(member)) {
return ongoing[i];
}
}
return null;
}
private function nextColour():void {
}
}
}
|
||||
package com.sqwiggle {
import com.sqwiggle.Conversation;
import com.sqwiggle.Self;
import com.sqwiggle.events.ApiEvent;
import flash.events.Event;
import flash.net.URLLoader;
import flash.events.EventDispatcher;
public class Conversations extends EventDispatcher {
private var ongoing:Object;
private var colours:Array;
private var self:Self;
public var members:Object;
public function Conversations(self:Self, members:Object) {
this.ongoing = new Object();
this.members = members;
this.self = self;
// make an API request to get ongoing conversations
var request = Api.getRequest('/conversations');
request.addEventListener(Event.COMPLETE, function(event:ApiEvent) {
updateMembers(event.data.conversations);
});
}
public function updateMembers(conversations:Object):void {
if (!conversations) {
Sqwiggle.trace('No conversations left');
for (var o in ongoing) {
ongoing[0].removeAllMembers();
}
conversations = new Object();
return;
}
// first find if the current user is in any conversation
var selfInConversation = false;
for (var a in conversations) {
for (var b in conversations[a].users) {
if (conversations[a].users[b].id == self.userId) {
selfInConversation = a;
}
}
}
for (var i in conversations) {
trace('updating conversation', i);
// we dont know about this conversation
if (!ongoing[i]) {
ongoing[i] = new Conversation();
ongoing[i].id = i;
}
var conversation = ongoing[i];
var existingMembers = conversation.members;
var selfInCurrentConversation = selfInConversation == i;
var member;
// find existing members that should leave the convo
for (var j in existingMembers) {
// check if this user is still in the convo
var filter = conversations[i].users.filter(function(user){ return user.id == this.userId; }, existingMembers[j]);
var inConversation = !!filter.length;
member = existingMembers[j];
if (!inConversation) {
trace('removing member from conversation', member.userId, conversation.id);
conversation.removeMember(member, selfInCurrentConversation);
}
}
// for every user that should be in this conversation
for (var k in conversations[i].users) {
var user = conversations[i].users[k];
if (user.id == self.userId) {
member = self;
} else {
member = members[user.id];
}
if (!member) {
continue;
}
if (!conversation.hasMember(member)) {
if (selfInCurrentConversation) {
trace('member already in a conversation with you');
} else {
trace('adding member to conversation', member.userId, conversation.id);
}
conversation.addMember(member, selfInCurrentConversation);
}
}
}
dispatchEvent(new Event("conversationsupdated"));
}
public function getConversationForMember(member:Member):Conversation {
for (var i in ongoing) {
if (ongoing[i].hasMember(member)) {
return ongoing[i];
}
}
return null;
}
private function nextColour():void {
}
}
}
|
@ -1 +1 @@
|
||||
package com.sqwiggle {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.MovieClip;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamInfo;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import fl.transitions.Tween;
import fl.transitions.easing.*;
public class Member extends Sprite {
public static const MAX_WIDTH = 400;
public static const MAX_HEIGHT = 300;
public static const INFOBAR_HEIGHT = 35;
public var connection :NetConnection;
public var userId :String;
public var peerId :String;
public var userName :String;
protected var stream :NetStream;
protected var video :Video;
protected var infoBar :Sprite;
protected var activity :MovieClip;
public function Member(userId:String, peerId:String, userName:String='Anonymous') {
this.userId = userId;
this.peerId = peerId;
this.userName = userName;
render(300, 225);
addEventListener(MouseEvent.MOUSE_OVER, hoverOver);
addEventListener(MouseEvent.MOUSE_OUT, hoverOut);
addEventListener(Event.ENTER_FRAME, updateActivity);
}
public function render(w:Number, h:Number):void {
w = Math.min(Member.MAX_WIDTH, w);
h = Math.min(Member.MAX_HEIGHT, h);
if (!video) {
video = new Video();
addChild(video);
}
if (!activity) {
activity = new ActivityIndicator();
addChild(activity);
}
activity.x = 0;
activity.y = w;
activity.visible = false;
video.width = w;
video.height = h;
drawInfoBar();
}
private function drawInfoBar():void {
if (infoBar) removeChild(infoBar);
infoBar = new Sprite();
infoBar.y = video.height-Member.INFOBAR_HEIGHT;
infoBar.alpha = 0;
addChild(infoBar);
var opaqueBar = new Sprite();
opaqueBar.graphics.beginFill(0x000000, 0.3);
opaqueBar.graphics.drawRect(0,0,video.width,Member.INFOBAR_HEIGHT);
opaqueBar.graphics.endFill();
infoBar.addChild(opaqueBar);
var textFormat:TextFormat = new TextFormat();
textFormat.font = "Arial";
textFormat.size = 20;
var nameField = new TextField();
nameField.x = 10;
nameField.y = 4; // padding
nameField.width = video.width;
nameField.height = infoBar.height;
nameField.selectable = false;
nameField.textColor = 0xFFFFFF;
nameField.text = userName;
nameField.setTextFormat(textFormat);
nameField.alpha = 0.8;
infoBar.addChild(nameField);
}
public function connectToVideo(connection:NetConnection):void {
trace('Connecting to video of: ' + userId + ', stream: ' + peerId);
stream = new NetStream(connection, peerId);
stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
stream.receiveAudio(false);
stream.play(userId);
video.attachNetStream(stream);
}
public function disconnectFromVideo():void {
removeChild(video);
stream.close();
}
public function updateActivity(event:Event):void {
var bytes:Number = stream.info.audioBytesPerSecond;
if (bytes) {
var maxActivityLevel = 5500;
var activityLevel = (Math.max(0, bytes-1000)/100) / (maxActivityLevel/100)
trace('Mic Activity', Math.round(activityLevel));
activity.alpha = activityLevel;
}
}
public function audioOn(conversationInProgress:Boolean=false):void {
stream.receiveAudio(true);
activity.visible = true;
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 0.5, true);
}
}
public function audioOff(conversationInProgress:Boolean=false):void {
stream.receiveAudio(false);
activity.visible = false;
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 1, true);
}
}
public function onNetStatus(event:NetStatusEvent):void {
trace('Net status ' + peerId + ': ' + event.info.code);
}
private function hoverOver(event:MouseEvent):void {
new Tween(infoBar, "alpha", Regular.easeIn, 0, 1, 0.3, true);
}
private function hoverOut(event:MouseEvent):void {
new Tween(infoBar, "alpha", Regular.easeIn, 1, 0, 0.3, true);
}
}
}
|
||||
package com.sqwiggle {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.MovieClip;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamInfo;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import fl.transitions.Tween;
import fl.transitions.easing.*;
public class Member extends Sprite {
public static const MAX_WIDTH = 400;
public static const MAX_HEIGHT = 300;
public static const INFOBAR_HEIGHT = 35;
public var connection :NetConnection;
public var userId :String;
public var peerId :String;
public var userName :String;
protected var stream :NetStream;
protected var video :Video;
protected var infoBar :Sprite;
protected var activity :MovieClip;
public function Member(userId:String, peerId:String, userName:String='Anonymous') {
this.userId = userId;
this.peerId = peerId;
this.userName = userName;
render(300, 225);
addEventListener(MouseEvent.MOUSE_OVER, hoverOver);
addEventListener(MouseEvent.MOUSE_OUT, hoverOut);
addEventListener(Event.ENTER_FRAME, updateActivity);
}
public function render(w:Number, h:Number):void {
w = Math.min(Member.MAX_WIDTH, w);
h = Math.min(Member.MAX_HEIGHT, h);
if (!video) {
video = new Video();
addChild(video);
}
video.width = w;
video.height = h;
if (!activity) {
activity = new ActivityIndicator();
activity.visible = false;
addChild(activity);
}
activity.x = w;
activity.y = 0;
drawInfoBar();
}
private function drawInfoBar():void {
if (infoBar) removeChild(infoBar);
infoBar = new Sprite();
infoBar.y = video.height-Member.INFOBAR_HEIGHT;
infoBar.alpha = 0;
addChild(infoBar);
var opaqueBar = new Sprite();
opaqueBar.graphics.beginFill(0x000000, 0.3);
opaqueBar.graphics.drawRect(0,0,video.width,Member.INFOBAR_HEIGHT);
opaqueBar.graphics.endFill();
infoBar.addChild(opaqueBar);
var textFormat:TextFormat = new TextFormat();
textFormat.font = "Arial";
textFormat.size = 20;
var nameField = new TextField();
nameField.x = 10;
nameField.y = 4; // padding
nameField.width = video.width;
nameField.height = infoBar.height;
nameField.selectable = false;
nameField.textColor = 0xFFFFFF;
nameField.text = userName;
nameField.setTextFormat(textFormat);
nameField.alpha = 0.8;
infoBar.addChild(nameField);
}
public function connectToVideo(connection:NetConnection):void {
Sqwiggle.trace('Connecting to video of: ' + userId + ', stream: ' + peerId);
stream = new NetStream(connection, peerId);
stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
stream.receiveAudio(false);
stream.play(userId);
video.attachNetStream(stream);
}
public function disconnectFromVideo():void {
removeChild(video);
stream.close();
}
public function updateActivity(event:Event):void {
var bytes:Number = stream.info.audioBytesPerSecond;
if (bytes) {
var maxActivityLevel = 5500;
var activityLevel = (Math.max(0, bytes-1000)/100) / (maxActivityLevel/100)
activity.alpha = activityLevel;
}
}
public function audioOn(conversationInProgress:Boolean=false):void {
stream.receiveAudio(true);
activity.visible = true;
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 0.5, true);
}
}
public function audioOff(conversationInProgress:Boolean=false):void {
stream.receiveAudio(false);
activity.visible = false;
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 1, true);
}
}
public function onNetStatus(event:NetStatusEvent):void {
Sqwiggle.trace('Net status ' + peerId + ': ' + event.info.code);
}
private function hoverOver(event:MouseEvent):void {
new Tween(infoBar, "alpha", Regular.easeIn, 0, 1, 0.3, true);
}
private function hoverOut(event:MouseEvent):void {
new Tween(infoBar, "alpha", Regular.easeIn, 1, 0, 0.3, true);
}
}
}
|
@ -1 +1 @@
|
||||
package com.sqwiggle {
import flash.events.NetStatusEvent;
import flash.media.Camera;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Microphone;
import flash.media.SoundCodec;
import flash.events.MouseEvent;
import flash.events.Event;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import com.sqwiggle.Member;
public class Self extends Member {
var cam:Camera;
var mic:Microphone;
public function Self(userId:String) {
super(userId, '', 'Me');
// TODO: check for camera
cam = Camera.getCamera();
cam.setQuality(0, 100);
// TODO: check for mic
mic = Microphone.getMicrophone();
mic.enableVAD = true;
mic.codec = SoundCodec.SPEEX;
mic.encodeQuality = 10;
mic.setSilenceLevel(100);
mic.setUseEchoSuppression(true);
}
public function updatePeerId():void {
var options = new Object();
options.peer_id = peerId;
// make an API request to save the new peerID
var request = Api.putRequest('/users/update', options);
// dispatch an event once the peerID is updated
request.addEventListener(Event.COMPLETE, function(event:Event) {
dispatchEvent(new Event("Connected"));
});
}
public override function updateActivity(event:Event):void {
if (mic) {
activity.alpha = 80 + (mic.activityLevel/5);
}
}
public override function connectToVideo(connection:NetConnection):void {
peerId = connection.nearID;
trace('Publishing video to: ' + userId + ', stream: ' + peerId);
var stream = new NetStream(connection, NetStream.DIRECT_CONNECTIONS);
stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
stream.attachCamera(this.cam);
stream.attachAudio(this.mic);
stream.publish(this.userId);
var client:Object = new Object();
client.onPeerConnect = function(caller:NetStream):Boolean {
trace('Member connecting to your video stream: ' + caller.farID);
return true;
};
stream.client = client;
video.attachCamera(this.cam);
video.smoothing = true;
video.deblocking = 5;
// ensure we update this users peerID on the server for
// other clients to connect to.
updatePeerId();
}
public override function audioOn(conversationInProgress:Boolean=false):void {
mic.setSilenceLevel(0);
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 0.5, true);
}
trace('Your audio is on');
}
public override function audioOff(conversationInProgress:Boolean=false):void {
mic.setSilenceLevel(100);
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 1, true);
}
trace('Your audio is off');
}
}
}
|
||||
package com.sqwiggle {
import flash.events.NetStatusEvent;
import flash.media.Camera;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Microphone;
import flash.media.SoundCodec;
import flash.events.MouseEvent;
import flash.events.Event;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import com.sqwiggle.Member;
public class Self extends Member {
var cam:Camera;
var mic:Microphone;
public function Self(userId:String) {
super(userId, '', 'Me');
// TODO: check for camera
cam = Camera.getCamera();
cam.setQuality(0, 100);
// TODO: check for mic
mic = Microphone.getMicrophone();
mic.enableVAD = true;
mic.codec = SoundCodec.SPEEX;
mic.encodeQuality = 10;
mic.setSilenceLevel(100);
mic.setUseEchoSuppression(true);
}
public function updatePeerId():void {
var options = new Object();
options.peer_id = peerId;
// make an API request to save the new peerID
var request = Api.putRequest('/users/update', options);
// dispatch an event once the peerID is updated
request.addEventListener(Event.COMPLETE, function(event:Event) {
dispatchEvent(new Event("Connected"));
});
}
public override function updateActivity(event:Event):void {
if (mic) {
activity.alpha = 80 + (mic.activityLevel/5);
}
}
public override function connectToVideo(connection:NetConnection):void {
peerId = connection.nearID;
Sqwiggle.trace('Publishing video to: ' + userId + ', stream: ' + peerId);
var stream = new NetStream(connection, NetStream.DIRECT_CONNECTIONS);
stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
stream.attachCamera(this.cam);
stream.attachAudio(this.mic);
stream.publish(this.userId);
var client:Object = new Object();
client.onPeerConnect = function(caller:NetStream):Boolean {
Sqwiggle.trace('Member connecting to your video stream: ' + caller.farID);
return true;
};
stream.client = client;
video.attachCamera(this.cam);
video.smoothing = true;
video.deblocking = 5;
// ensure we update this users peerID on the server for
// other clients to connect to.
updatePeerId();
}
public override function audioOn(conversationInProgress:Boolean=false):void {
mic.setSilenceLevel(0);
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 0.5, true);
}
Sqwiggle.trace('Your audio is on');
}
public override function audioOff(conversationInProgress:Boolean=false):void {
mic.setSilenceLevel(100);
if (conversationInProgress) {
new Tween(video, "alpha", Regular.easeIn, 1, alpha, 1, true);
}
Sqwiggle.trace('Your audio is off');
}
}
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
p2p.fla
BIN
p2p.fla
Binary file not shown.
Loading…
Reference in New Issue
Block a user