From 582cc82c8ae2cec11ffe3b031bc80668b5923ea7 Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Wed, 27 Nov 2013 09:23:50 +0900 Subject: [PATCH 1/9] Add autoreload feature --- app/cocoa/ui_table_view.rb | 21 +++++++++++++++++++++ app/controller/timeline_view_controller.rb | 21 +++++++-------------- 2 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 app/cocoa/ui_table_view.rb diff --git a/app/cocoa/ui_table_view.rb b/app/cocoa/ui_table_view.rb new file mode 100644 index 0000000..d61cf16 --- /dev/null +++ b/app/cocoa/ui_table_view.rb @@ -0,0 +1,21 @@ +class UITableView + def reloadDataWithKeepingSelectedRowAnimated(animated) + indexPath = self.indexPathForSelectedRow + self.reloadData + # self.reloadDataWithRowAnimation(UITableViewRowAnimationNone) + self.selectRowAtIndexPath(indexPath, animated:animated, scrollPosition:UITableViewScrollPositionNone); + end + + def reloadDataWithRowAnimation(animation) + indexSet = NSIndexSet.indexSetWithIndex(0) + self.reloadSections(indexSet, withRowAnimation:animation) + end + + def reloadDataWithDeselectingRowAnimated(animated) + indexPath = self.indexPathForSelectedRow + self.reloadData + # self.reloadDataWithRowAnimation(UITableViewRowAnimationNone) + self.selectRowAtIndexPath(indexPath, animated:animated, scrollPosition:UITableViewScrollPositionNone); + self.deselectRowAtIndexPath(indexPath, animated:animated); + end +end diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index 920ffab..b3b6420 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -49,6 +49,7 @@ def viewDidLoad self.tableView.addGestureRecognizer( UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'on_long_press_row:') ) + self.receive_application_switch_notifcation end def on_long_press_row(recog) @@ -131,7 +132,7 @@ def paginate def observeValueForKeyPath(keyPath, ofObject:object, change:change, context:context) if (@bookmarks == object and keyPath == 'bookmarks') - view.reloadData + view.reloadDataWithKeepingSelectedRowAnimated(true) end if (ApplicationUser.sharedUser == object and keyPath == 'hatena_id' and self.home?) @@ -159,26 +160,15 @@ def update_title end def viewWillAppear(animated) - self.receive_application_switch_notifcation self.update_title self.navigationController.setToolbarHidden(true, animated:true) - - indexPath = tableView.indexPathForSelectedRow - tableView.reloadData - tableView.selectRowAtIndexPath(indexPath, animated:animated, scrollPosition:UITableViewScrollPositionNone); - tableView.deselectRowAtIndexPath(indexPath, animated:animated); - + tableView.reloadDataWithDeselectingRowAnimated(animated) @indicator.center = [ view.center.x, view.center.y - 42 ] @footer_indicator.center = [@footerView.frame.size.width / 2, @footerView.frame.size.height / 2] super end - def viewWillDisappear(animated) - self.unreceive_application_switch_notification - super - end - def tableView(tableView, numberOfRowsInSection:section) return @bookmarks.size end @@ -241,12 +231,15 @@ def on_refresh end def applicationWillEnterForeground + # FIXME: 新ユーザーページの時且つTimelineだけ + @bookmarks.update(true) ## 相対時刻更新 - self.tableView.reloadData + self.view.reloadDataWithKeepingSelectedRowAnimated(true) end def dealloc self.removeObserver + self.unreceive_application_switch_notification NSLog("dealloc: " + self.class.name) super end From c502043bb958f88af9551bb3f643ef4288fac7f7 Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Wed, 27 Nov 2013 11:13:15 +0900 Subject: [PATCH 2/9] Keep contentOffset --- app/controller/timeline_view_controller.rb | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index b3b6420..c965cc8 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -22,6 +22,7 @@ def removeObserver def viewDidLoad super + @last_bookmarks_size = 0 @bookmarks = self.initialize_feed_manager(self.user) self.view.backgroundColor = UIColor.whiteColor @@ -132,7 +133,27 @@ def paginate def observeValueForKeyPath(keyPath, ofObject:object, change:change, context:context) if (@bookmarks == object and keyPath == 'bookmarks') - view.reloadDataWithKeepingSelectedRowAnimated(true) + if @last_bookmarks_size == 0 or @last_bookmarks_size == @bookmarks.size + view.reloadDataWithKeepingSelectedRowAnimated(true) + @last_bookmarks_size = @bookmarks.size + else + # 末尾の時のことはとりあえず後で考える -> ひとまず insert は巧くいっているが、ポジション固定はできてない + size = @bookmarks.size - @last_bookmarks_size + @last_bookmarks_size = @bookmarks.size + + offset = view.contentOffset + view.reloadData + for i in (0..size - 1) do + offset.y += self.tableView( + view, + heightForRowAtIndexPath:NSIndexPath.indexPathForRow(0, inSection:0) + ) + end + if offset.y > view.contentSize.height + offset.y = 0 + end + view.setContentOffset(offset) + end end if (ApplicationUser.sharedUser == object and keyPath == 'hatena_id' and self.home?) From 64da35554796b24fbc099ea9540a60143e9b643b Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Wed, 27 Nov 2013 12:49:11 +0900 Subject: [PATCH 3/9] Guard offset based timeline --- app/controller/timeline_view_controller.rb | 45 +++++++++++++--------- app/model/feed_manager.rb | 16 ++++++++ 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index c965cc8..f03ae07 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -133,26 +133,17 @@ def paginate def observeValueForKeyPath(keyPath, ofObject:object, change:change, context:context) if (@bookmarks == object and keyPath == 'bookmarks') - if @last_bookmarks_size == 0 or @last_bookmarks_size == @bookmarks.size - view.reloadDataWithKeepingSelectedRowAnimated(true) + if @bookmarks.timebased? and + @bookmarks.prepended? and + @last_bookmarks_size != 0 and + @last_bookmarks_size != @bookmarks.size + + size = @bookmarks.size - @last_bookmarks_size @last_bookmarks_size = @bookmarks.size + self.tableView(view, reloadDataWithKeepingContentOffset:size) else - # 末尾の時のことはとりあえず後で考える -> ひとまず insert は巧くいっているが、ポジション固定はできてない - size = @bookmarks.size - @last_bookmarks_size + view.reloadDataWithKeepingSelectedRowAnimated(true) @last_bookmarks_size = @bookmarks.size - - offset = view.contentOffset - view.reloadData - for i in (0..size - 1) do - offset.y += self.tableView( - view, - heightForRowAtIndexPath:NSIndexPath.indexPathForRow(0, inSection:0) - ) - end - if offset.y > view.contentSize.height - offset.y = 0 - end - view.setContentOffset(offset) end end @@ -165,6 +156,21 @@ def observeValueForKeyPath(keyPath, ofObject:object, change:change, context:cont end end + def tableView(tableView, reloadDataWithKeepingContentOffset:prependedRowSize) + offset = tableView.contentOffset + tableView.reloadData + for i in (0..prependedRowSize - 1) do + offset.y += self.tableView( + tableView, + heightForRowAtIndexPath:NSIndexPath.indexPathForRow(0, inSection:0) + ) + end + if offset.y > tableView.contentSize.height + offset.y = 0 + end + tableView.setContentOffset(offset) + end + ## 末尾付近に来たら次のフィードを読み込む (paging) def tableView(tableView, willDisplayCell:cell, forRowAtIndexPath:indexPath) if (not @bookmarks.updating? and @bookmarks.size > 0 and indexPath.row >= @bookmarks.size - 5) @@ -252,8 +258,9 @@ def on_refresh end def applicationWillEnterForeground - # FIXME: 新ユーザーページの時且つTimelineだけ - @bookmarks.update(true) + if self.home? and @bookmarks.timebased? + @bookmarks.update(true) + end ## 相対時刻更新 self.view.reloadDataWithKeepingSelectedRowAnimated(true) end diff --git a/app/model/feed_manager.rb b/app/model/feed_manager.rb index 0e6eb24..fd986b4 100644 --- a/app/model/feed_manager.rb +++ b/app/model/feed_manager.rb @@ -16,6 +16,7 @@ def initialize @url = nil @bookmarks = [] @updating = nil + @last_update_method = nil end def size @@ -94,6 +95,7 @@ def prepend(bookmarks) ## test # dt = bookmarks[4].datetime # bookmarks.insert(5, Placeholder.new(5, dt)) + @last_update_method = 'prepend' origin_size = @bookmarks.size boundary = bookmarks.size @@ -110,6 +112,7 @@ def prepend(bookmarks) end def append(bookmarks) + @last_update_method = 'append' self << bookmarks end @@ -126,6 +129,7 @@ def uniq! end def replace(i, bookmarks) + @last_update_method = 'replace' ## 取ってきたフィードそのものに被りがあると上手くいかないので先に uniq bookmarks.uniq! { |b| b.id } @@ -162,6 +166,14 @@ def replace_placeholder(ph, &cb) cb.call(response) if cb end end + + def prepended? + @last_update_method == 'prepend' + end + + def timebased? + true + end end class Offset < FeedManager @@ -181,5 +193,9 @@ def prepend(bookmarks) def append(bookmarks) self << bookmarks end + + def timebased? + false + end end end From c408fce16a811794d8fb6c23915310937c523dcf Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Wed, 27 Nov 2013 13:12:42 +0900 Subject: [PATCH 4/9] Update timeline when remote notification receive --- .../module/remote_push_notification_event.rb | 19 +++++++++++++++++++ app/controller/timeline_view_controller.rb | 9 +++++++++ app/remote_notification_delegate.rb | 6 ++++++ 3 files changed, 34 insertions(+) create mode 100644 app/controller/module/remote_push_notification_event.rb diff --git a/app/controller/module/remote_push_notification_event.rb b/app/controller/module/remote_push_notification_event.rb new file mode 100644 index 0000000..e34846d --- /dev/null +++ b/app/controller/module/remote_push_notification_event.rb @@ -0,0 +1,19 @@ +module HBFav2 + module RemotePushNotificationEvent + def receive_remote_push_notifcation_event + @receive_remote_push_notification_ = true + nc = NSNotificationCenter.defaultCenter + nc.addObserver(self, selector:"applicationDidReceiveRemoteNotification:", name:"applicationDidReceiveRemoteNotification", object:nil) + end + + def applicationDidReceiveRemoteNotification(userInfo) + end + + def unreceive_remote_push_notification_event + if @receive_remote_push_notification_ + nc = NSNotificationCenter.defaultCenter + nc.removeObserver(self, name:"applicationDidReceiveRemoteNotification:", object:nil) + end + end + end +end diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index f03ae07..f69e9f8 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -2,6 +2,7 @@ class TimelineViewController < HBFav2::UITableViewController attr_accessor :user, :content_type include HBFav2::ApplicationSwitchNotification + include HBFav2::RemotePushNotificationEvent DefaultTitle = "HBFav" @@ -51,6 +52,7 @@ def viewDidLoad UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'on_long_press_row:') ) self.receive_application_switch_notifcation + self.receive_remote_push_notifcation_event end def on_long_press_row(recog) @@ -265,9 +267,16 @@ def applicationWillEnterForeground self.view.reloadDataWithKeepingSelectedRowAnimated(true) end + def applicationDidReceiveRemoteNotification(userInfo) + if self.home? and @bookmarks.timebased? + @bookmarks.update(true) + end + end + def dealloc self.removeObserver self.unreceive_application_switch_notification + self.unreceive_remote_push_notification_event NSLog("dealloc: " + self.class.name) super end diff --git a/app/remote_notification_delegate.rb b/app/remote_notification_delegate.rb index b60b32d..f5fdbf7 100644 --- a/app/remote_notification_delegate.rb +++ b/app/remote_notification_delegate.rb @@ -38,6 +38,12 @@ def application(application, didReceiveRemoteNotification:userInfo) banner.detailTextLabel.font = UIFont.systemFontOfSize(13) banner.detailTextLabel.textColor = "#333333".uicolor end + + ## 他の画面でローカルpushイベントを採れるように、発火 + notify = NSNotification.notificationWithName( + "applicationDidReceiveRemoteNotification", object:userInfo + ) + NSNotificationCenter.defaultCenter.postNotification(notify) end when UIApplicationStateInactive then PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo) From 5306fe8104ec4799d9bf1bd600e169d346b476d8 Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Wed, 27 Nov 2013 14:25:57 +0900 Subject: [PATCH 5/9] Fix bug when resizing --- app/controller/timeline_view_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index f69e9f8..e71e3f8 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -87,7 +87,6 @@ def initialize_bookmarks self.refreshControl.update_title(res.error_message) else self.refreshControl.update_title - # tableView.reloadData ## 要らない模様 (observerで更新される) if @bookmarks.size > 0 @footer_indicator.startAnimating else @@ -140,6 +139,7 @@ def observeValueForKeyPath(keyPath, ofObject:object, change:change, context:cont @last_bookmarks_size != 0 and @last_bookmarks_size != @bookmarks.size + ## FIXME: 差分の割り出しは本当は change オブジェクトを使うべき size = @bookmarks.size - @last_bookmarks_size @last_bookmarks_size = @bookmarks.size self.tableView(view, reloadDataWithKeepingContentOffset:size) @@ -164,7 +164,7 @@ def tableView(tableView, reloadDataWithKeepingContentOffset:prependedRowSize) for i in (0..prependedRowSize - 1) do offset.y += self.tableView( tableView, - heightForRowAtIndexPath:NSIndexPath.indexPathForRow(0, inSection:0) + heightForRowAtIndexPath:NSIndexPath.indexPathForRow(i, inSection:0) ) end if offset.y > tableView.contentSize.height From 01b2ca520c1ab74293b62795391586e6a826be05 Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Thu, 28 Nov 2013 07:24:19 +0900 Subject: [PATCH 6/9] Fix selection issue when a placeholder replaced #70 --- app/controller/timeline_view_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index e71e3f8..288ee87 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -223,6 +223,7 @@ def tableView(tableView, cellForRowAtIndexPath:indexPath) def tableView(tableView, didSelectRowAtIndexPath:indexPath) bookmark = @bookmarks[indexPath.row] + if bookmark.kind_of? Placeholder cell = tableView.cellForRowAtIndexPath(indexPath) cell.beginRefreshing @@ -230,6 +231,7 @@ def tableView(tableView, didSelectRowAtIndexPath:indexPath) @bookmarks.replace_placeholder(bookmark) do |response| self.refreshControl.endRefreshing cell.endRefreshing + tableView.deselectRowAtIndexPath(indexPath, animated:true) end else controller = BookmarkViewController.new.tap { |c| c.bookmark = @bookmarks[indexPath.row] } From a821eafb94b8e07c730b809362b02280fae05de1 Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Thu, 28 Nov 2013 07:24:53 +0900 Subject: [PATCH 7/9] Update comment --- app/model/feed_manager.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/model/feed_manager.rb b/app/model/feed_manager.rb index fd986b4..b51fdce 100644 --- a/app/model/feed_manager.rb +++ b/app/model/feed_manager.rb @@ -92,9 +92,10 @@ def prepend(bookmarks) if @bookmarks.size > 0 and bookmarks.first.id == @bookmarks.first.id # 新着なし else - ## test + ## 以下二行テスト用 # dt = bookmarks[4].datetime # bookmarks.insert(5, Placeholder.new(5, dt)) + @last_update_method = 'prepend' origin_size = @bookmarks.size From 3c76fa341479951d0efff80693d12a9ed2ee345c Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Thu, 28 Nov 2013 07:25:36 +0900 Subject: [PATCH 8/9] Turn off BugSense on iOS simulator --- app/app_delegate.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app_delegate.rb b/app/app_delegate.rb index def4f42..eae1769 100644 --- a/app/app_delegate.rb +++ b/app/app_delegate.rb @@ -18,7 +18,7 @@ def application(application, didFinishLaunchingWithOptions:launchOptions) app_user = ApplicationUser.sharedUser.load ## initialize BugSense - if app_user.send_bugreport? + if not Device.simulator? and app_user.send_bugreport? BugSenseController.sharedControllerWithBugSenseAPIKey( app_config.vars['bugsense']['api_key'] ) From 79622738c8a72772b331a3d4460ee331250b578a Mon Sep 17 00:00:00 2001 From: Naoya Ito Date: Thu, 28 Nov 2013 08:19:12 +0900 Subject: [PATCH 9/9] Add periodic timer --- Rakefile | 1 + app/controller/timeline_view_controller.rb | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/Rakefile b/Rakefile index f509b65..ea3e716 100644 --- a/Rakefile +++ b/Rakefile @@ -5,6 +5,7 @@ require 'bundler/setup' Bundler.require :default require 'sugarcube-attributedstring' +require 'bubble-wrap/reactor' Motion::Project::App.setup do |app| # Use `rake config' to see complete project settings. diff --git a/app/controller/timeline_view_controller.rb b/app/controller/timeline_view_controller.rb index 288ee87..01b5001 100644 --- a/app/controller/timeline_view_controller.rb +++ b/app/controller/timeline_view_controller.rb @@ -53,6 +53,7 @@ def viewDidLoad ) self.receive_application_switch_notifcation self.receive_remote_push_notifcation_event + self.start_periodic_update(60.0) end def on_long_press_row(recog) @@ -275,6 +276,15 @@ def applicationDidReceiveRemoteNotification(userInfo) end end + def start_periodic_update(interval = 60.0) + EM.add_periodic_timer interval do + if self.home? and @bookmarks.timebased? + NSLog("Attempting to update timeline...") + @bookmarks.update(true) + end + end + end + def dealloc self.removeObserver self.unreceive_application_switch_notification