Ind.ie is now Small Technology Foundation.
Commit bb0b56df authored by Aral Balkan's avatar Aral Balkan

Updated All Friends message notifications. They now display the first inline...

Updated All Friends message notifications. They now display the first inline image in a message if there is one and they have reply functionality. Replies are not coming in in the correct order and the profile image is hardcoded to the receiver’s, not the senders.
parent f10d0b05
import Cocoa
//let urlString = "download://aral/all-friends/from/aral/000000027-2015-06-02T19_03_59.365Z/Photo%20on%2031-05-2015%20at%2013.49%20%234.jpg.zip"
let a:String = "<p><img src=\"/all-friends/to/000000019-2015-08-03T20_32_42.397Z/set-hello-world-badge.png\" alt=\"set-hello-world-badge.png\"></p>"
let urlString = "download://aral/all-friends/to/000000027-2015-06-02T19_03_59.365Z/Photo%20on%2031-05-2015%20at%2013.49%20%234.jpg.zip"
a.componentsSeparatedByString("<img src=\"/all-friends/to/")[1].componentsSeparatedByString("\" alt=")[0]
let url = NSURL(string: urlString)
if let url = url, theProtocol = url.scheme, theCommand = url.host
{
println("here")
let theArguments = url.pathComponents
if theProtocol == "download"
{
println("ℹ️ Download requested for \(theCommand) with arguments: \(theArguments)")
if let theArguments = theArguments, downloadTimeline = theArguments[1] as? String, linkType = theArguments[2] as? String
{
var downloadFolderIndex = 3
var downloadFileNameIndex = 4
if linkType == "from"
{
downloadFolderIndex == 4
downloadFileNameIndex == 5
}
if let downloadFolder = theArguments[downloadFolderIndex] as? String, downloadFileName = theArguments[downloadFileNameIndex] as? String
{
//
// Currently only supporting All Friends.
//
if downloadTimeline != "all-friends"
{
println("Not all friends!")
}
if theCommand == "xxx"
{
// It’s us:
println("It’s us!")
let rootPath = NSHomeDirectory().stringByAppendingPathComponent("/Pulse/Sync/3. All your friends/to/")
let filePath = (rootPath as NSString).stringByAppendingPathComponent("\(downloadFolder)/\(downloadFileName)")
//NSWorkspace.sharedWorkspace().selectFile(filePath, inFileViewerRootedAtPath: rootPath)
println("filePath: \(filePath)")
}
else
{
// It’s a different person
println("It’s a different person!")
let rootPath = NSHomeDirectory().stringByAppendingPathComponent("/Pulse/Sync/3. All your friends/from/")
let filePath = (rootPath as NSString).stringByAppendingPathComponent("\(theCommand)/\(downloadFolder)/\(downloadFileName)")
//NSWorkspace.sharedWorkspace().selectFile(filePath, inFileViewerRootedAtPath: rootPath)
println("filePath: \(filePath)")
}
}
}
}
}
......@@ -2,5 +2,10 @@
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=105&amp;CharacterRangeLoc=165&amp;EndingColumnNumber=106&amp;EndingLineNumber=4&amp;StartingColumnNumber=1&amp;StartingLineNumber=4&amp;Timestamp=460327673.874081"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
......@@ -71,34 +71,76 @@ public class NativeNotification: NSObject, NSUserNotificationCenterDelegate
//
// Notification handlers.
//
allFriendsTimelineUpdateHandler = handle(PulseNotification.named(PulseNotification.AllFriendsTimelineUpdated), with: {
allFriendsTimelineUpdateHandler = allFriendsTimelineUpdateHandler ?? handle(PulseNotification.named(PulseNotification.AllFriendsTimelineUpdated), with: {
notification in
println("GOT ALL FRIENDS NOTIFICATION!!!!!!!!!!!!!!")
println(notification)
let n:NSUserNotification = NSUserNotification()
n.setValue(false, forKey: "_identityImageHasBorder")
n.title = "New message in the All Friends timeline."
n.hasActionButton = true
// n.subtitle = fullName
// n.informativeText = accountHandle
// TODO: Get the image passed in also.
// n.contentImage = i
n.actionButtonTitle = "View"
n.otherButtonTitle = "Ignore"
n.userInfo = ["type": NativeNotificationType.named(.AllFriendsTimelineMessage)] //,"accountHandle": accountHandle, "name": fullName, "deviceID": deviceID]
//
// Private
//
n.setValue(true, forKey: "_showsButtons")
n.setValue(true, forKey: "_poofsOnCancel")
if let userInfo = notification.userInfo, data:AnyObject = userInfo["data"], repo = data["repo"] as? String, name = data["name"] as? String
{
var fromPerson = repo.componentsSeparatedByString("-")[0]
var filePath = NSHomeDirectory().stringByAppendingPathComponent("Pulse/Sync").stringByAppendingPathComponent("3. All your friends/from/").stringByAppendingPathComponent(fromPerson).stringByAppendingPathComponent(name)
if let fileURL = NSURL(fileURLWithPath: filePath, isDirectory: false), message = NSString(contentsOfURL: fileURL, encoding: NSUTF8StringEncoding, error: nil)
{
let messageWithoutHTML = (message as String).stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)
println("Mesage: \(messageWithoutHTML)")
let n:NSUserNotification = NSUserNotification()
n.title = fromPerson + " (to all friends)"
// n.hasActionButton = true
n.informativeText = messageWithoutHTML
// Reply button
n.responsePlaceholder = "Reply"
n.hasReplyButton = true
//
// Check if an image was passed in the message and, if so, display the first one.
//
let componentsSeparatedByImageTags = (message as String).stringByReplacingOccurrencesOfString("\n", replacement: "").componentsSeparatedByString("<img src=\"/all-friends/to/")
if componentsSeparatedByImageTags.count >= 2
{
// Get the first image and use it as the content image of the notification.
let imageInMessageRelativePath = componentsSeparatedByImageTags[1].componentsSeparatedByString("\" alt=")[0]
println("Image in message relative path: \(imageInMessageRelativePath)")
let imageFilePath = NSHomeDirectory().stringByAppendingPathComponent("Pulse/Sync").stringByAppendingPathComponent("3. All your friends/from/").stringByAppendingPathComponent(fromPerson).stringByAppendingPathComponent(imageInMessageRelativePath)
if let imageFileURL = NSURL(fileURLWithPath: imageFilePath, isDirectory: false), contentImage = NSImage(contentsOfURL: imageFileURL)
{
n.contentImage = contentImage
}
}
// n.actionButtonTitle = "View"
// n.otherButtonTitle = "Dismiss"
// This is a private API and could result in a rejection on the app store.
// Leaving it in for now as it’s an experience issue.
n.setValue(SetupData.photoWithRoundedCorners, forKey: "_identityImage")
n.setValue(false, forKey: "_identityImageHasBorder")
n.userInfo = ["type": NativeNotificationType.named(.AllFriendsTimelineMessage)] //,"accountHandle": accountHandle, "name": fullName, "deviceID": deviceID]
//
// Private
//
n.setValue(true, forKey: "_showsButtons")
n.setValue(true, forKey: "_poofsOnCancel")
NSUserNotificationCenter.defaultUserNotificationCenter().deliverNotification(n)
}
}
NSUserNotificationCenter.defaultUserNotificationCenter().deliverNotification(n)
})
}
......@@ -172,14 +214,15 @@ public class NativeNotification: NSObject, NSUserNotificationCenterDelegate
println("Did activate notification: \(notification)")
println("User info: \(notification.userInfo)")
if notification.activationType != NSUserNotificationActivationType.ActionButtonClicked
{
println("The user did not click the accept button, ignoring.")
return
}
if let userInfo = notification.userInfo, type = userInfo["type"] as? String
{
if notification.activationType != NSUserNotificationActivationType.ActionButtonClicked && type != "AllFriendsTimelineMessage"
{
println("The user did not click the accept button on a friendship request, ignoring.")
return
}
println("Received a notification activation on native notification of type \(type).")
switch type
......@@ -196,12 +239,31 @@ public class NativeNotification: NSObject, NSUserNotificationCenterDelegate
post(NativeNotificationActionNotification.named(.FriendshipRequestAccepted), from: self, with: userInfo)
}
case NativeNotificationType.named(.AllFriendsTimelineMessage):
println("Person has asked to view the All Friends Timeline…showing it!")
//
// Switch to the timeline.
//
let timelineNavigationRequestUserInfo = ["timeline":Timelines.sharedInstance[.AllFriends]!]
post(TimelineNavigationRequestNotification, from: nil, with: timelineNavigationRequestUserInfo)
//
// If there is a reply, send it.
//
if notification.activationType == NSUserNotificationActivationType.Replied
{
let reply = notification.response!.string
println("You’ve requested that we send a reply: \(reply)")
post(MessageNotification.named(.SendMessage), from: nil, with: ["message": NSAttributedString(string: reply)])
}
let userInfo = ["timeline":Timelines.sharedInstance[.AllFriends]!]
post(TimelineNavigationRequestNotification, from: nil, with: userInfo)
// Remove the notification
NSUserNotificationCenter.defaultUserNotificationCenter().removeDeliveredNotification(notification)
default:
fatalError("Unknown native notification type received: \(type).")
......
......@@ -68,6 +68,17 @@ struct SetupData
}
}
static var photoWithRoundedCorners:NSImage
{
get
{
let photo = self.photo
let photoWithRoundedCorners = SetupData.roundCorners(photo, width: photo.size.width, height: photo.size.height)
return photoWithRoundedCorners
}
}
static var photoPath:String
{
get
......@@ -154,5 +165,36 @@ struct SetupData
return true
}
}
//
// MARK: - Round corners of profile image
//
// Courtesy: Paul Miller et. al.
// http://stackoverflow.com/a/27157566
//
static func roundCorners(image: NSImage, width: CGFloat = 192, height: CGFloat = 192) -> NSImage {
let xRad = width / 2
let yRad = height / 2
let existing = image
let esize = existing.size
let newSize = NSMakeSize(esize.height, esize.width)
let composedImage = NSImage(size: newSize)
composedImage.lockFocus()
let ctx = NSGraphicsContext.currentContext()
ctx?.imageInterpolation = NSImageInterpolation.High
let imageFrame = NSRect(x: 0, y: 0, width: width, height: height)
let clipPath = NSBezierPath(roundedRect: imageFrame, xRadius: xRad, yRadius: yRad)
clipPath.windingRule = NSWindingRule.EvenOddWindingRule
clipPath.addClip()
let rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
image.drawAtPoint(NSZeroPoint, fromRect: rect, operation: NSCompositingOperation.CompositeSourceOver, fraction: 1)
composedImage.unlockFocus()
return composedImage
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment