Merge branch 'develop' of https://github.com/CatchChat/Yep into develop

This commit is contained in:
kevinzhow
2015-09-17 15:55:40 +08:00
9 changed files with 372 additions and 286 deletions
+14
View File
@@ -124,6 +124,7 @@
5056AD6E1B05CB92003F9359 /* ProfileSocialAccountImagesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5056AD6C1B05CB92003F9359 /* ProfileSocialAccountImagesCell.swift */; };
5056AD6F1B05CB92003F9359 /* ProfileSocialAccountImagesCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5056AD6D1B05CB92003F9359 /* ProfileSocialAccountImagesCell.xib */; };
505A48401B4E70CB00C3A301 /* RegisterSelectSkillsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505A483F1B4E70CB00C3A301 /* RegisterSelectSkillsLayout.swift */; };
505C338B1BAA92CA00E044E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 505C338D1BAA92CA00E044E2 /* InfoPlist.strings */; };
505EC8131ADE607D001D27E0 /* SkillCategoryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC8121ADE607D001D27E0 /* SkillCategoryButton.swift */; };
505EC8171ADF8151001D27E0 /* SkillCategoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC8151ADF8151001D27E0 /* SkillCategoryCell.swift */; };
505EC8181ADF8151001D27E0 /* SkillCategoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 505EC8161ADF8151001D27E0 /* SkillCategoryCell.xib */; };
@@ -386,6 +387,8 @@
5056AD6C1B05CB92003F9359 /* ProfileSocialAccountImagesCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProfileSocialAccountImagesCell.swift; path = Views/Cells/ProfileSocialAccount/ProfileSocialAccountImagesCell.swift; sourceTree = "<group>"; };
5056AD6D1B05CB92003F9359 /* ProfileSocialAccountImagesCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = ProfileSocialAccountImagesCell.xib; path = Views/Cells/ProfileSocialAccount/ProfileSocialAccountImagesCell.xib; sourceTree = "<group>"; };
505A483F1B4E70CB00C3A301 /* RegisterSelectSkillsLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RegisterSelectSkillsLayout.swift; path = ViewControllers/Register/RegisterSelectSkillsLayout.swift; sourceTree = "<group>"; };
505C338C1BAA92CA00E044E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
505C338E1BAA92CD00E044E2 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
505EC8121ADE607D001D27E0 /* SkillCategoryButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SkillCategoryButton.swift; path = Views/Buttons/SkillCategoryButton.swift; sourceTree = "<group>"; };
505EC8151ADF8151001D27E0 /* SkillCategoryCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SkillCategoryCell.swift; path = Views/Cells/SkillCategory/SkillCategoryCell.swift; sourceTree = "<group>"; };
505EC8161ADF8151001D27E0 /* SkillCategoryCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = SkillCategoryCell.xib; path = Views/Cells/SkillCategory/SkillCategoryCell.xib; sourceTree = "<group>"; };
@@ -632,6 +635,7 @@
0A8F54B91AB67D11004AD60E /* LaunchScreen.xib */,
0A8F54AE1AB67D11004AD60E /* Supporting Files */,
5008A1951B8DB8B500E94274 /* Localizable.strings */,
505C338D1BAA92CA00E044E2 /* InfoPlist.strings */,
);
path = Yep;
sourceTree = "<group>";
@@ -1809,6 +1813,7 @@
buildActionMask = 2147483647;
files = (
5023DE381AB6979600B3EE96 /* ConversationCell.xib in Resources */,
505C338B1BAA92CA00E044E2 /* InfoPlist.strings in Resources */,
50C090A11ADE391600CC6389 /* AddSkillsReusableView.xib in Resources */,
504F415B1AD5028200FBB19A /* SkillCell.xib in Resources */,
50E348931B9063A700A8E699 /* AboutCell.xib in Resources */,
@@ -2164,6 +2169,15 @@
name = Intro.storyboard;
sourceTree = "<group>";
};
505C338D1BAA92CA00E044E2 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
505C338C1BAA92CA00E044E2 /* en */,
505C338E1BAA92CD00E044E2 /* zh-Hans */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
+3 -51
View File
@@ -32,57 +32,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
let directory: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(YepConfig.appGroupID)!
let realmPath = directory.path!.stringByAppendingPathComponent("db.realm")
return Realm.Configuration(path: realmPath, schemaVersion: 17, migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 9 {
migration.enumerate(Message.className()) { oldObject, newObject in
let createdAt = oldObject!["createdAt"] as! NSDate
let updatedAt = oldObject!["updatedAt"] as! NSDate
newObject!["createdUnixTime"] = createdAt.timeIntervalSince1970
newObject!["updatedUnixTime"] = updatedAt.timeIntervalSince1970
}
migration.enumerate(Conversation.className()) { oldObject, newObject in
let updatedAt = oldObject!["updatedAt"] as! NSDate
newObject!["updatedUnixTime"] = updatedAt.timeIntervalSince1970
}
}
if oldSchemaVersion < 10 {
migration.enumerate(User.className()) { oldObject, newObject in
let createdAt = oldObject!["createdAt"] as! NSDate
let lastSignInAt = oldObject!["lastSignInAt"] as! NSDate
newObject!["createdUnixTime"] = createdAt.timeIntervalSince1970
newObject!["lastSignInUnixTime"] = lastSignInAt.timeIntervalSince1970
}
migration.enumerate(Group.className()) { oldObject, newObject in
let createdAt = oldObject!["createdAt"] as! NSDate
newObject!["createdUnixTime"] = createdAt.timeIntervalSince1970
}
}
if oldSchemaVersion < 14 {
migration.enumerate(Message.className()) { oldObject, newObject in
let metaDataString = oldObject!["metaData"] as! String
if !metaDataString.isEmpty {
if let data = metaDataString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let mediaMetaData = MediaMetaData()
mediaMetaData.data = data
newObject!["mediaMetaData"] = mediaMetaData
}
}
}
}
if oldSchemaVersion < 17 {
}
return Realm.Configuration(path: realmPath, schemaVersion: 0, migrationBlock: { migration, oldSchemaVersion in
})
}
@@ -142,6 +92,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
NSNotificationCenter.defaultCenter().postNotificationName(MessageToolbar.Notification.updateDraft, object: nil)
}
func applicationWillEnterForeground(application: UIApplication) {
+2 -2
View File
@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>88</string>
<string>89</string>
<key>Fabric</key>
<dict>
<key>APIKey</key>
@@ -55,7 +55,7 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Find pepole around you</string>
<string>Meeting with near genius</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
+22 -19
View File
@@ -1118,30 +1118,33 @@ let parseDiscoveredUser: JSONDictionary -> DiscoveredUser? = { userInfo in
createdUnixTime = userInfo["created_at"] as? NSTimeInterval,
lastSignInUnixTime = userInfo["last_sign_in_at"] as? NSTimeInterval,
longitude = userInfo["longitude"] as? Double,
latitude = userInfo["latitude"] as? Double,
//distance = userInfo["distance"] as? Double,
masterSkillsData = userInfo["master_skills"] as? [JSONDictionary],
learningSkillsData = userInfo["learning_skills"] as? [JSONDictionary],
socialAccountProvidersInfo = userInfo["providers"] as? [String: Bool] {
latitude = userInfo["latitude"] as? Double {
let username = userInfo["username"] as? String
let masterSkills = skillsFromSkillsData(masterSkillsData)
let learningSkills = skillsFromSkillsData(learningSkillsData)
var socialAccountProviders = Array<DiscoveredUser.SocialAccountProvider>()
for (name, enabled) in socialAccountProvidersInfo {
let provider = DiscoveredUser.SocialAccountProvider(name: name, enabled: enabled)
socialAccountProviders.append(provider)
}
let introduction = userInfo["introduction"] as? String
let badge = userInfo["badge"] as? String
let distance = userInfo["distance"] as? Double
var masterSkills: [Skill] = []
if let masterSkillsData = userInfo["master_skills"] as? [JSONDictionary] {
masterSkills = skillsFromSkillsData(masterSkillsData)
}
var learningSkills: [Skill] = []
if let learningSkillsData = userInfo["learning_skills"] as? [JSONDictionary] {
learningSkills = skillsFromSkillsData(learningSkillsData)
}
var socialAccountProviders = Array<DiscoveredUser.SocialAccountProvider>()
if let socialAccountProvidersInfo = userInfo["providers"] as? [String: Bool] {
for (name, enabled) in socialAccountProvidersInfo {
let provider = DiscoveredUser.SocialAccountProvider(name: name, enabled: enabled)
socialAccountProviders.append(provider)
}
}
let discoverUser = DiscoveredUser(id: id, username: username, nickname: nickname, introduction: introduction, avatarURLString: avatarURLString, badge: badge, createdUnixTime: createdUnixTime, lastSignInUnixTime: lastSignInUnixTime, longitude: longitude, latitude: latitude, distance: distance, masterSkills: masterSkills, learningSkills: learningSkills, socialAccountProviders: socialAccountProviders)
return discoverUser
@@ -1152,7 +1155,7 @@ let parseDiscoveredUser: JSONDictionary -> DiscoveredUser? = { userInfo in
let parseDiscoveredUsers: JSONDictionary -> [DiscoveredUser]? = { data in
//println("discoverUsers: \(data)")
println("discoverUsers: \(data)")
if let usersData = data["users"] as? [JSONDictionary] {
@@ -190,15 +190,10 @@ class ConversationViewController: BaseViewController {
NSNotificationCenter.defaultCenter().removeObserver(self)
YepUserDefaults.avatarURLString.removeListenerWithName(Listener.Avatar)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// NavigationControllerDelegate push
if let delegate = originalNavigationControllerDelegate {
navigationController?.delegate = delegate
}
conversationCollectionView.delegate = nil
println("deinit ConversationViewController")
}
override func viewDidLoad() {
@@ -325,27 +320,103 @@ class ConversationViewController: BaseViewController {
}
}
}
func tryRecoverMessageToolBar() {
if let
draft = conversation.draft,
state = MessageToolbarState(rawValue: draft.messageToolbarState) {
if state == .TextInputing || state == .Default {
messageToolbar.messageTextView.text = draft.text
}
//
if state == .TextInputing || state == .BeginTextInput {
// messageToolbar.state
return
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// NavigationControllerDelegate push
if let delegate = originalNavigationControllerDelegate {
navigationController?.delegate = delegate
}
if isFirstAppear {
// 稿
messageToolbar.conversation = conversation
// MARK: MessageToolbar State Transitions
messageToolbar.stateTransitionAction = { [weak self] (messageToolbar, previousState, currentState) in
if let strongSelf = self {
switch (previousState, currentState) {
case (.MoreMessages, .Default): fallthrough
case (.MoreMessages, .VoiceRecord):
dispatch_async(dispatch_get_main_queue()) { [weak self] in
UIView.animateWithDuration(0.2, delay: 0.0, options: .CurveEaseInOut, animations: { _ in
strongSelf.conversationCollectionView.contentOffset.y -= strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.conversationCollectionView.contentInset.bottom = strongSelf.messageToolbar.frame.height
strongSelf.messageToolbarBottomConstraint.constant = 0
strongSelf.view.layoutIfNeeded()
}, completion: { finished in
})
}
default:
if currentState == .MoreMessages {
if previousState != .BeginTextInput && previousState != .TextInputing {
dispatch_async(dispatch_get_main_queue()) { [weak self] in
UIView.animateWithDuration(0.2, delay: 0.0, options: .CurveEaseInOut, animations: { _ in
strongSelf.conversationCollectionView.contentOffset.y += strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.conversationCollectionView.contentInset.bottom = strongSelf.messageToolbar.frame.height + strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.messageToolbarBottomConstraint.constant = strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.view.layoutIfNeeded()
}, completion: { finished in
})
}
}
// touch to create (if need) for faster appear
delay(0.2) {
self?.imagePicker.hidesBarsOnTap = false
}
}
}
}
// stateTransitionAction
//
if state == .VoiceRecord {
messageToolbar.state = state
}
// messageToolbar stateTransitionAction
func tryRecoverMessageToolBar() {
if let
draft = conversation.draft,
state = MessageToolbarState(rawValue: draft.messageToolbarState) {
if state == .TextInputing || state == .Default {
messageToolbar.messageTextView.text = draft.text
}
//
if state == .TextInputing || state == .BeginTextInput {
// messageToolbar.state
return
}
// stateTransitionAction
//
if state == .VoiceRecord {
messageToolbar.state = state
}
}
}
tryRecoverMessageToolBar()
}
}
@@ -369,19 +440,22 @@ class ConversationViewController: BaseViewController {
}
}).map({ self.markMessageAsReaded($0) })
// MARK: Notify Typing
// nil
if checkTypingStatusTimer == nil {
checkTypingStatusTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("checkTypingStatus"), userInfo: nil, repeats: true)
}
//
if isFirstAppear {
isFirstAppear = false
// MARK: Notify Typing
messageToolbar.notifyTypingAction = { [weak self] in
checkTypingStatusTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("checkTypingStatus"), userInfo: nil, repeats: true)
messageToolbar.notifyTypingAction = {
if let withFriend = self.conversation.withFriend {
if let withFriend = self?.conversation.withFriend {
let typingMessage: JSONDictionary = ["state": FayeService.InstantStateType.Text.rawValue]
@@ -644,87 +718,6 @@ class ConversationViewController: BaseViewController {
self?.swipeUpPromptLabel.text = text
}
// MARK: MessageToolbar State Transitions
messageToolbar.stateTransitionAction = { [weak self] (messageToolbar, previousState, currentState) in
if let strongSelf = self {
switch (previousState, currentState) {
case (.MoreMessages, .Default): fallthrough
case (.MoreMessages, .VoiceRecord):
dispatch_async(dispatch_get_main_queue()) { [weak self] in
UIView.animateWithDuration(0.2, delay: 0.0, options: .CurveEaseInOut, animations: { _ in
strongSelf.conversationCollectionView.contentOffset.y -= strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.conversationCollectionView.contentInset.bottom = strongSelf.messageToolbar.frame.height
strongSelf.messageToolbarBottomConstraint.constant = 0
strongSelf.view.layoutIfNeeded()
}, completion: { finished in
})
}
default:
if currentState == .MoreMessages {
if previousState != .BeginTextInput && previousState != .TextInputing {
dispatch_async(dispatch_get_main_queue()) { [weak self] in
UIView.animateWithDuration(0.2, delay: 0.0, options: .CurveEaseInOut, animations: { _ in
strongSelf.conversationCollectionView.contentOffset.y += strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.conversationCollectionView.contentInset.bottom = strongSelf.messageToolbar.frame.height + strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.messageToolbarBottomConstraint.constant = strongSelf.moreMessageTypesViewDefaultHeight
strongSelf.view.layoutIfNeeded()
}, completion: { finished in
})
}
}
// touch to create (if need) for faster appear
delay(0.2) {
self?.imagePicker.hidesBarsOnTap = false
}
}
}
// 稿
let realm = Realm()
if let draft = strongSelf.conversation.draft {
realm.write {
draft.messageToolbarState = currentState.rawValue
if currentState == .BeginTextInput || currentState == .TextInputing {
draft.text = messageToolbar.messageTextView.text
}
}
} else {
let draft = Draft()
draft.messageToolbarState = currentState.rawValue
realm.write {
strongSelf.conversation.draft = draft
}
}
}
}
// messageToolbar stateTransitionAction
tryRecoverMessageToolBar()
// MARK: More Message Types
choosePhotoButton.title = NSLocalizedString("Choose photo", comment: "")
@@ -798,13 +791,20 @@ class ConversationViewController: BaseViewController {
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().postNotificationName(MessageToolbar.Notification.updateDraft, object: nil)
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
FayeService.sharedManager.delegate = nil
checkTypingStatusTimer?.invalidate()
checkTypingStatusTimer = nil //
self.waverView.removeFromSuperview()
waverView.removeFromSuperview()
}
override func viewDidLayoutSubviews() {
@@ -2087,7 +2087,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
self?.performSegueWithIdentifier("showMessageMedia", sender: message)
} else {
YepAlert.alertSorry(message: NSLocalizedString("Please wait while the image is not ready!", comment: ""), inViewController: self)
//YepAlert.alertSorry(message: NSLocalizedString("Please wait while the image is not ready!", comment: ""), inViewController: self)
}
}, collectionView: collectionView, indexPath: indexPath)
@@ -2105,7 +2105,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
self?.playMessageAudioWithMessage(message)
} else {
YepAlert.alertSorry(message: NSLocalizedString("Please wait while the audio is not ready!", comment: ""), inViewController: self)
//YepAlert.alertSorry(message: NSLocalizedString("Please wait while the audio is not ready!", comment: ""), inViewController: self)
}
}, collectionView: collectionView, indexPath: indexPath)
@@ -2129,7 +2129,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
self?.performSegueWithIdentifier("showMessageMedia", sender: message)
} else {
YepAlert.alertSorry(message: NSLocalizedString("Please wait while the video is not ready!", comment: ""), inViewController: self)
//YepAlert.alertSorry(message: NSLocalizedString("Please wait while the video is not ready!", comment: ""), inViewController: self)
}
}, collectionView: collectionView, indexPath: indexPath)
@@ -78,6 +78,52 @@ enum ProfileUser {
case DiscoveredUserType(DiscoveredUser)
case UserType(User)
var userID: String {
switch self {
case .DiscoveredUserType(let discoveredUser):
return discoveredUser.id
case .UserType(let user):
return user.userID
}
}
var username: String? {
var username: String? = nil
switch self {
case .DiscoveredUserType(let discoveredUser):
username = discoveredUser.username
case .UserType(let user):
if !user.username.isEmpty {
username = user.username
}
}
return username
}
var avatarURLString: String? {
var avatarURLString: String? = nil
switch self {
case .DiscoveredUserType(let discoveredUser):
avatarURLString = discoveredUser.avatarURLString
case .UserType(let user):
if !user.avatarURLString.isEmpty {
avatarURLString = user.avatarURLString
}
}
return avatarURLString
}
var isMe: Bool {
let userID: String
@@ -400,20 +446,12 @@ class ProfileViewController: UIViewController {
if let profileUser = profileUser {
let userID: String
switch profileUser {
case .DiscoveredUserType(let discoveredUser):
userID = discoveredUser.id
customNavigationItem.title = discoveredUser.nickname
case .UserType(let user):
userID = user.userID
customNavigationItem.title = user.nickname
if user.friendState == UserFriendState.Me.rawValue {
@@ -427,6 +465,8 @@ class ProfileViewController: UIViewController {
if !profileUserIsMe {
let userID = profileUser.userID
userInfoOfUserWithUserID(userID, failureHandler: nil, completion: { [weak self] userInfo in
//println("userInfoOfUserWithUserID \(userInfo)")
@@ -434,6 +474,15 @@ class ProfileViewController: UIViewController {
updateUserWithUserID(userID, useUserInfo: userInfo)
if let discoveredUser = parseDiscoveredUser(userInfo) {
switch profileUser {
case .DiscoveredUserType:
self?.profileUser = ProfileUser.DiscoveredUserType(discoveredUser)
default:
break
}
}
self?.updateProfileCollectionView()
})
}
@@ -454,11 +503,19 @@ class ProfileViewController: UIViewController {
}
}
// share button
// share my profile button
if customNavigationItem.leftBarButtonItem == nil {
let shareButton = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: "tryShareProfile")
customNavigationItem.leftBarButtonItem = shareButton
let shareMyProfileButton = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: "tryShareMyProfile")
customNavigationItem.leftBarButtonItem = shareMyProfileButton
}
} else {
// share others' profile button
if let _ = profileUser.username {
let shareOthersProfileButton = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: "shareOthersProfile")
customNavigationItem.rightBarButtonItem = shareOthersProfileButton
}
}
}
@@ -491,105 +548,102 @@ class ProfileViewController: UIViewController {
// MARK: Actions
func tryShareProfile() {
private func shareProfile() {
if let
myUserID = YepUserDefaults.userID.value,
me = userWithUserID(myUserID, inRealm: Realm()) {
if let username = profileUser?.username, profileURL = NSURL(string: "http://soyep.com/\(username)") {
let username = me.username
MonkeyKing.registerAccount(.WeChat(appID: YepConfig.ChinaSocialNetwork.WeChat.appID))
let shareProfileWithUsername: String -> Void = { [weak self] username in
var thumbnail: UIImage?
if let profileURL = NSURL(string: "http://soyep.com/\(username)") {
if let
avatarURLString = profileUser?.avatarURLString,
avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()) {
if let
avatarFileURL = NSFileManager.yepAvatarURLWithName(avatar.avatarFileName),
avatarFilePath = avatarFileURL.path,
image = UIImage(contentsOfFile: avatarFilePath) {
thumbnail = image.roundImageOfRadius(50)
}
}
MonkeyKing.registerAccount(.WeChat(appID: YepConfig.ChinaSocialNetwork.WeChat.appID))
let info = MonkeyKing.Message.WeChatSubtype.Info(
title: NSLocalizedString("Match me if you can", comment: ""),
description: NSLocalizedString("From Yep with Skills", comment: ""),
thumbnail: thumbnail,
media: .URL(profileURL)
)
var thumbnail: UIImage?
let sessionMessage = MonkeyKing.Message.WeChat(.Session(info))
let weChatSessionActivity = WeChatActivity(
type: .Session,
canPerform: sessionMessage.canBeDelivered,
perform: {
MonkeyKing.shareMessage(sessionMessage) { success in
println("share Profile to WeChat Session success: \(success)")
}
}
)
let timelineMessage = MonkeyKing.Message.WeChat(.Timeline(info))
let weChatTimelineActivity = WeChatActivity(
type: .Timeline,
canPerform: timelineMessage.canBeDelivered,
perform: {
MonkeyKing.shareMessage(timelineMessage) { success in
println("share Profile to WeChat Timeline success: \(success)")
}
}
)
let activityViewController = UIActivityViewController(activityItems: [profileURL], applicationActivities: [weChatSessionActivity, weChatTimelineActivity])
self.presentViewController(activityViewController, animated: true, completion: nil)
}
}
func tryShareMyProfile() {
if let _ = profileUser?.username {
shareProfile()
} else {
YepAlert.textInput(title: NSLocalizedString("Create a username", comment: ""), message: NSLocalizedString("In order to share your profile, create a unique username first.", comment: ""), placeholder: NSLocalizedString("use letters, numbers, and underscore", comment: ""), oldText: nil, confirmTitle: NSLocalizedString("Create", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { text in
let newUsername = text
updateMyselfWithInfo(["username": newUsername], failureHandler: { [weak self] reason, errorMessage in
defaultFailureHandler(reason, errorMessage)
YepAlert.alertSorry(message: errorMessage ?? NSLocalizedString("Create username failed!", comment: ""), inViewController: self)
}, completion: { success in
dispatch_async(dispatch_get_main_queue()) { [weak self] in
let realm = Realm()
if let
avatarURLString = YepUserDefaults.avatarURLString.value,
avatar = avatarWithAvatarURLString(avatarURLString, inRealm: Realm()) {
if let
avatarFileURL = NSFileManager.yepAvatarURLWithName(avatar.avatarFileName),
avatarFilePath = avatarFileURL.path,
image = UIImage(contentsOfFile: avatarFilePath) {
thumbnail = image.roundImageOfRadius(50)
myUserID = YepUserDefaults.userID.value,
me = userWithUserID(myUserID, inRealm: realm) {
realm.write {
me.username = newUsername
}
}
let info = MonkeyKing.Message.WeChatSubtype.Info(
title: NSLocalizedString("Match me if you can", comment: ""),
description: NSLocalizedString("From Yep with Skills", comment: ""),
thumbnail: thumbnail,
media: .URL(profileURL)
)
let sessionMessage = MonkeyKing.Message.WeChat(.Session(info))
let weChatSessionActivity = WeChatActivity(
type: .Session,
canPerform: sessionMessage.canBeDelivered,
perform: {
MonkeyKing.shareMessage(sessionMessage) { success in
println("share Profile to WeChat Session success: \(success)")
}
}
)
let timelineMessage = MonkeyKing.Message.WeChat(.Timeline(info))
let weChatTimelineActivity = WeChatActivity(
type: .Timeline,
canPerform: timelineMessage.canBeDelivered,
perform: {
MonkeyKing.shareMessage(timelineMessage) { success in
println("share Profile to WeChat Timeline success: \(success)")
}
}
)
let activityViewController = UIActivityViewController(activityItems: [profileURL], applicationActivities: [weChatSessionActivity, weChatTimelineActivity])
self?.presentViewController(activityViewController, animated: true, completion: nil)
self?.shareProfile()
}
}
})
if username.isEmpty {
YepAlert.textInput(title: NSLocalizedString("Create a username", comment: ""), message: NSLocalizedString("In order to share your profile, create a unique username first.", comment: ""), placeholder: NSLocalizedString("use letters, numbers, and underscore", comment: ""), oldText: nil, confirmTitle: NSLocalizedString("Create", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { text in
let newUsername = text
updateMyselfWithInfo(["username": newUsername], failureHandler: { [weak self] reason, errorMessage in
defaultFailureHandler(reason, errorMessage)
YepAlert.alertSorry(message: errorMessage ?? NSLocalizedString("Create username failed!", comment: ""), inViewController: self)
}, completion: { success in
dispatch_async(dispatch_get_main_queue()) {
let realm = Realm()
if let
myUserID = YepUserDefaults.userID.value,
me = userWithUserID(myUserID, inRealm: realm) {
realm.write {
me.username = newUsername
}
}
shareProfileWithUsername(newUsername)
}
})
}, cancelAction: {
})
} else {
shareProfileWithUsername(username)
}
}, cancelAction: {
})
}
}
func shareOthersProfile() {
shareProfile()
}
func pickSkills() {
let storyboard = UIStoryboard(name: "Intro", bundle: nil)
+48 -3
View File
@@ -38,6 +38,22 @@ class MessageToolbar: UIToolbar {
let messageTextAttributes = [NSFontAttributeName: UIFont.systemFontOfSize(15)]
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
struct Notification {
static let updateDraft = "UpdateDraftOfConversation"
}
var conversation: Conversation? {
willSet {
if let conversation = newValue {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateDraft:", name: Notification.updateDraft, object: nil)
}
}
}
var stateTransitionAction: ((messageToolbar: MessageToolbar, previousState: MessageToolbarState, currentState: MessageToolbarState) -> Void)?
var previousState: MessageToolbarState = .Default
@@ -84,6 +100,8 @@ class MessageToolbar: UIToolbar {
messageTextView.hidden = true
voiceRecordButton.hidden = false
messageTextView.text = nil
micButton.setImage(UIImage(named: "icon_keyboard"), forState: .Normal)
micButton.tintColor = UIColor.messageToolBarNormalColor()
@@ -272,8 +290,8 @@ class MessageToolbar: UIToolbar {
func showVoiceButtonAnimation() {
let animation = CABasicAnimation(keyPath: "cornerRadius")
animation.fromValue = voiceRecordButton.layer.cornerRadius
let newCornerRadius = CGRectGetHeight(voiceRecordButton.bounds) * 0.5
animation.fromValue = normalCornerRadius
let newCornerRadius: CGFloat = 17
animation.toValue = newCornerRadius
animation.timingFunction = CAMediaTimingFunction(name: "easeInEaseOut")
animation.repeatCount = 0
@@ -281,7 +299,7 @@ class MessageToolbar: UIToolbar {
voiceRecordButton.layer.addAnimation(animation, forKey: "cornerRadius")
voiceRecordButton.layer.cornerRadius = newCornerRadius
messageTextView.layer.cornerRadius = CGRectGetHeight(messageTextView.bounds) * 0.5
messageTextView.layer.cornerRadius = newCornerRadius
}
func hideVoiceButtonAnimation() {
@@ -320,6 +338,33 @@ class MessageToolbar: UIToolbar {
// MARK: Actions
func updateDraft(notification: NSNotification) {
if let conversation = conversation, realm = conversation.realm {
if let draft = conversation.draft {
realm.write { [weak self] in
if let strongSelf = self {
draft.messageToolbarState = strongSelf.state.rawValue
if strongSelf.state == .BeginTextInput || strongSelf.state == .TextInputing {
draft.text = strongSelf.messageTextView.text
}
}
}
} else {
let draft = Draft()
draft.messageToolbarState = state.rawValue
realm.write {
conversation.draft = draft
}
}
}
}
func trySendTextMessage() {
if let textSendAction = textSendAction {
textSendAction(messageToolBar: self)
+9
View File
@@ -0,0 +1,9 @@
/*
InfoPlist.strings
Yep
Created by nixzhu on 15/9/17.
Copyright (c) 2015年 Catch Inc. All rights reserved.
*/
"NSLocationWhenInUseUsageDescription" = "Meeting with near genius";
+9
View File
@@ -0,0 +1,9 @@
/*
InfoPlist.strings
Yep
Created by nixzhu on 15/9/17.
Copyright (c) 2015年 Catch Inc. All rights reserved.
*/
"NSLocationWhenInUseUsageDescription" = "与附近的天才相遇";