{"action":"created","comment":{"url":"https://api.github.com/repos/duckduckgo/iOS/pulls/comments/215218751","pull_request_review_id":152433214,"id":215218751,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxNTIxODc1MQ==","diff_hunk":"@@ -49,4 +69,30 @@ public class Tab: NSObject, NSCoding {\n         guard let other = other as? Tab else { return false }\n         return link == other.link\n     }\n+    \n+    func addObserver(_ observer: TabObserver) {\n+        guard indexOf(observer) == nil else { return }\n+        observersHolder.append(WeaklyHeldTabObserver(observer: observer))\n+    }\n+    \n+    func removeObserver(_ observer: TabObserver) {\n+        guard let index = indexOf(observer) else { return }\n+        observersHolder.remove(at: index)\n+    }\n+    \n+    private func indexOf(_ observer: TabObserver) -> Int? {\n+        return liveHolders().index(where: { $0.observer === observer })\n+    }\n+    \n+    private func notifyObservers() {\n+        for holder in liveHolders() {\n+            holder.observer?.didChange(tab: self)\n+        }\n+    }\n+    \n+    private func liveHolders() -> [WeaklyHeldTabObserver] {","path":"DuckDuckGo/Tab.swift","position":63,"original_position":63,"commit_id":"dd62a7a3e552c287dc7c2db2ef6dcd419f973ac2","original_commit_id":"dd62a7a3e552c287dc7c2db2ef6dcd419f973ac2","user":{"login":"subsymbolic","id":1652407,"node_id":"MDQ6VXNlcjE2NTI0MDc=","avatar_url":"https://avatars1.githubusercontent.com/u/1652407?v=4","gravatar_id":"","url":"https://api.github.com/users/subsymbolic","html_url":"https://github.com/subsymbolic","followers_url":"https://api.github.com/users/subsymbolic/followers","following_url":"https://api.github.com/users/subsymbolic/following{/other_user}","gists_url":"https://api.github.com/users/subsymbolic/gists{/gist_id}","starred_url":"https://api.github.com/users/subsymbolic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/subsymbolic/subscriptions","organizations_url":"https://api.github.com/users/subsymbolic/orgs","repos_url":"https://api.github.com/users/subsymbolic/repos","events_url":"https://api.github.com/users/subsymbolic/events{/privacy}","received_events_url":"https://api.github.com/users/subsymbolic/received_events","type":"User","site_admin":false},"body":"Can we make this a computed property rather than a function?","created_at":"2018-09-05T10:40:15Z","updated_at":"2018-09-05T10:44:30Z","html_url":"https://github.com/duckduckgo/iOS/pull/361#discussion_r215218751","pull_request_url":"https://api.github.com/repos/duckduckgo/iOS/pulls/361","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/duckduckgo/iOS/pulls/comments/215218751"},"html":{"href":"https://github.com/duckduckgo/iOS/pull/361#discussion_r215218751"},"pull_request":{"href":"https://api.github.com/repos/duckduckgo/iOS/pulls/361"}}},"pull_request":{"url":"https://api.github.com/repos/duckduckgo/iOS/pulls/361","id":213233952,"node_id":"MDExOlB1bGxSZXF1ZXN0MjEzMjMzOTUy","html_url":"https://github.com/duckduckgo/iOS/pull/361","diff_url":"https://github.com/duckduckgo/iOS/pull/361.diff","patch_url":"https://github.com/duckduckgo/iOS/pull/361.patch","issue_url":"https://api.github.com/repos/duckduckgo/iOS/issues/361","number":361,"state":"open","locked":false,"title":"improve tab state handling in tab switcher","user":{"login":"brindy","id":81197,"node_id":"MDQ6VXNlcjgxMTk3","avatar_url":"https://avatars0.githubusercontent.com/u/81197?v=4","gravatar_id":"","url":"https://api.github.com/users/brindy","html_url":"https://github.com/brindy","followers_url":"https://api.github.com/users/brindy/followers","following_url":"https://api.github.com/users/brindy/following{/other_user}","gists_url":"https://api.github.com/users/brindy/gists{/gist_id}","starred_url":"https://api.github.com/users/brindy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brindy/subscriptions","organizations_url":"https://api.github.com/users/brindy/orgs","repos_url":"https://api.github.com/users/brindy/repos","events_url":"https://api.github.com/users/brindy/events{/privacy}","received_events_url":"https://api.github.com/users/brindy/received_events","type":"User","site_admin":false},"body":"<!--\r\nNote: This checklist is a reminder of our shared engineering expectations. Feel free to change it, although assigning a GitHub reviewer and the items in bold are required.\r\n-->\r\n\r\nTask/Issue URL: https://app.asana.com/0/392891325557410/487656199561838\r\nTech Design URL:\r\nCC:\r\n\r\n**Description**:\r\n\r\nMakes tabs weakly observable so that changes of tabs loading in the background are reflected in the tab switcher.\r\n\r\n**Steps to test this PR**:\r\n\r\n1. Go to https://news.ycombinator.com/news\r\n1. Open a bunch of tabs in the background quite quickly\r\n1. Go to the tab switcher, note the titles updating in real time\r\n1. Close the current tab - the next logical tab becomes current and the tab updates its state\r\n1. Tap done and re-open the tab switcher. Note the tab state is now \"viewed\" (ie no blue dot)\r\n1. Tap another tab and re-open the tab switcher. Note the tab state is now \"viewed\" (ie no blue dot) \r\n1. Confirm no memory leaks\r\n\r\n---\r\n###### Internal references:\r\n[Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552)\r\n[Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943)","created_at":"2018-09-05T09:53:16Z","updated_at":"2018-09-05T10:44:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"169e3249c38fa4a394f90a0a1f5ff7f57ded087d","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/duckduckgo/iOS/pulls/361/commits","review_comments_url":"https://api.github.com/repos/duckduckgo/iOS/pulls/361/comments","review_comment_url":"https://api.github.com/repos/duckduckgo/iOS/pulls/comments{/number}","comments_url":"https://api.github.com/repos/duckduckgo/iOS/issues/361/comments","statuses_url":"https://api.github.com/repos/duckduckgo/iOS/statuses/dd62a7a3e552c287dc7c2db2ef6dcd419f973ac2","head":{"label":"duckduckgo:feature/improve_title_handling_in_tab_switcher","ref":"feature/improve_title_handling_in_tab_switcher","sha":"dd62a7a3e552c287dc7c2db2ef6dcd419f973ac2","user":{"login":"duckduckgo","id":342708,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM0MjcwOA==","avatar_url":"https://avatars2.githubusercontent.com/u/342708?v=4","gravatar_id":"","url":"https://api.github.com/users/duckduckgo","html_url":"https://github.com/duckduckgo","followers_url":"https://api.github.com/users/duckduckgo/followers","following_url":"https://api.github.com/users/duckduckgo/following{/other_user}","gists_url":"https://api.github.com/users/duckduckgo/gists{/gist_id}","starred_url":"https://api.github.com/users/duckduckgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duckduckgo/subscriptions","organizations_url":"https://api.github.com/users/duckduckgo/orgs","repos_url":"https://api.github.com/users/duckduckgo/repos","events_url":"https://api.github.com/users/duckduckgo/events{/privacy}","received_events_url":"https://api.github.com/users/duckduckgo/received_events","type":"Organization","site_admin":false},"repo":{"id":78868967,"node_id":"MDEwOlJlcG9zaXRvcnk3ODg2ODk2Nw==","name":"iOS","full_name":"duckduckgo/iOS","owner":{"login":"duckduckgo","id":342708,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM0MjcwOA==","avatar_url":"https://avatars2.githubusercontent.com/u/342708?v=4","gravatar_id":"","url":"https://api.github.com/users/duckduckgo","html_url":"https://github.com/duckduckgo","followers_url":"https://api.github.com/users/duckduckgo/followers","following_url":"https://api.github.com/users/duckduckgo/following{/other_user}","gists_url":"https://api.github.com/users/duckduckgo/gists{/gist_id}","starred_url":"https://api.github.com/users/duckduckgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duckduckgo/subscriptions","organizations_url":"https://api.github.com/users/duckduckgo/orgs","repos_url":"https://api.github.com/users/duckduckgo/repos","events_url":"https://api.github.com/users/duckduckgo/events{/privacy}","received_events_url":"https://api.github.com/users/duckduckgo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/duckduckgo/iOS","description":"DuckDuckGo iOS Application","fork":false,"url":"https://api.github.com/repos/duckduckgo/iOS","forks_url":"https://api.github.com/repos/duckduckgo/iOS/forks","keys_url":"https://api.github.com/repos/duckduckgo/iOS/keys{/key_id}","collaborators_url":"https://api.github.com/repos/duckduckgo/iOS/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/duckduckgo/iOS/teams","hooks_url":"https://api.github.com/repos/duckduckgo/iOS/hooks","issue_events_url":"https://api.github.com/repos/duckduckgo/iOS/issues/events{/number}","events_url":"https://api.github.com/repos/duckduckgo/iOS/events","assignees_url":"https://api.github.com/repos/duckduckgo/iOS/assignees{/user}","branches_url":"https://api.github.com/repos/duckduckgo/iOS/branches{/branch}","tags_url":"https://api.github.com/repos/duckduckgo/iOS/tags","blobs_url":"https://api.github.com/repos/duckduckgo/iOS/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/duckduckgo/iOS/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/duckduckgo/iOS/git/refs{/sha}","trees_url":"https://api.github.com/repos/duckduckgo/iOS/git/trees{/sha}","statuses_url":"https://api.github.com/repos/duckduckgo/iOS/statuses/{sha}","languages_url":"https://api.github.com/repos/duckduckgo/iOS/languages","stargazers_url":"https://api.github.com/repos/duckduckgo/iOS/stargazers","contributors_url":"https://api.github.com/repos/duckduckgo/iOS/contributors","subscribers_url":"https://api.github.com/repos/duckduckgo/iOS/subscribers","subscription_url":"https://api.github.com/repos/duckduckgo/iOS/subscription","commits_url":"https://api.github.com/repos/duckduckgo/iOS/commits{/sha}","git_commits_url":"https://api.github.com/repos/duckduckgo/iOS/git/commits{/sha}","comments_url":"https://api.github.com/repos/duckduckgo/iOS/comments{/number}","issue_comment_url":"https://api.github.com/repos/duckduckgo/iOS/issues/comments{/number}","contents_url":"https://api.github.com/repos/duckduckgo/iOS/contents/{+path}","compare_url":"https://api.github.com/repos/duckduckgo/iOS/compare/{base}...{head}","merges_url":"https://api.github.com/repos/duckduckgo/iOS/merges","archive_url":"https://api.github.com/repos/duckduckgo/iOS/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/duckduckgo/iOS/downloads","issues_url":"https://api.github.com/repos/duckduckgo/iOS/issues{/number}","pulls_url":"https://api.github.com/repos/duckduckgo/iOS/pulls{/number}","milestones_url":"https://api.github.com/repos/duckduckgo/iOS/milestones{/number}","notifications_url":"https://api.github.com/repos/duckduckgo/iOS/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/duckduckgo/iOS/labels{/name}","releases_url":"https://api.github.com/repos/duckduckgo/iOS/releases{/id}","deployments_url":"https://api.github.com/repos/duckduckgo/iOS/deployments","created_at":"2017-01-13T17:09:36Z","updated_at":"2018-09-04T16:23:14Z","pushed_at":"2018-09-05T09:53:16Z","git_url":"git://github.com/duckduckgo/iOS.git","ssh_url":"git@github.com:duckduckgo/iOS.git","clone_url":"https://github.com/duckduckgo/iOS.git","svn_url":"https://github.com/duckduckgo/iOS","homepage":"https://itunes.apple.com/us/app/duckduckgo-privacy-browser/id663592361?mt=8","size":15036,"stargazers_count":446,"watchers_count":446,"language":"Swift","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":65,"mirror_url":null,"archived":false,"open_issues_count":2,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":65,"open_issues":2,"watchers":446,"default_branch":"develop"}},"base":{"label":"duckduckgo:develop","ref":"develop","sha":"d1566c5dd44cd7da987da0c41a515b4e7a71ca79","user":{"login":"duckduckgo","id":342708,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM0MjcwOA==","avatar_url":"https://avatars2.githubusercontent.com/u/342708?v=4","gravatar_id":"","url":"https://api.github.com/users/duckduckgo","html_url":"https://github.com/duckduckgo","followers_url":"https://api.github.com/users/duckduckgo/followers","following_url":"https://api.github.com/users/duckduckgo/following{/other_user}","gists_url":"https://api.github.com/users/duckduckgo/gists{/gist_id}","starred_url":"https://api.github.com/users/duckduckgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duckduckgo/subscriptions","organizations_url":"https://api.github.com/users/duckduckgo/orgs","repos_url":"https://api.github.com/users/duckduckgo/repos","events_url":"https://api.github.com/users/duckduckgo/events{/privacy}","received_events_url":"https://api.github.com/users/duckduckgo/received_events","type":"Organization","site_admin":false},"repo":{"id":78868967,"node_id":"MDEwOlJlcG9zaXRvcnk3ODg2ODk2Nw==","name":"iOS","full_name":"duckduckgo/iOS","owner":{"login":"duckduckgo","id":342708,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM0MjcwOA==","avatar_url":"https://avatars2.githubusercontent.com/u/342708?v=4","gravatar_id":"","url":"https://api.github.com/users/duckduckgo","html_url":"https://github.com/duckduckgo","followers_url":"https://api.github.com/users/duckduckgo/followers","following_url":"https://api.github.com/users/duckduckgo/following{/other_user}","gists_url":"https://api.github.com/users/duckduckgo/gists{/gist_id}","starred_url":"https://api.github.com/users/duckduckgo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duckduckgo/subscriptions","organizations_url":"https://api.github.com/users/duckduckgo/orgs","repos_url":"https://api.github.com/users/duckduckgo/repos","events_url":"https://api.github.com/users/duckduckgo/events{/privacy}","received_events_url":"https://api.github.com/users/duckduckgo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/duckduckgo/iOS","description":"DuckDuckGo iOS Application","fork":false,"url":"https://api.github.com/repos/duckduckgo/iOS","forks_url":"https://api.github.com/repos/duckduckgo/iOS/forks","keys_url":"https://api.github.com/repos/duckduckgo/iOS/keys{/key_id}","collaborators_url":"https://api.github.com/repos/duckduckgo/iOS/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/duckduckgo/iOS/teams","hooks_url":"https://api.github.com/repos/duckduckgo/iOS/hooks","issue_events_url":"https://api.github.com/repos/duckduckgo/iOS/issues/events{/number}","events_url":"https://api.github.com/repos/duckduckgo/iOS/events","assignees_url":"https://api.github.com/repos/duckduckgo/iOS/assignees{/user}","branches_url":"https://api.github.com/repos/duckduckgo/iOS/branches{/branch}","tags_url":"https://api.github.com/repos/duckduckgo/iOS/tags","blobs_url":"https://api.github.com/repos/duckduckgo/iOS/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/duckduckgo/iOS/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/duckduckgo/iOS/git/refs{/sha}","trees_url":"https://api.github.com/repos/duckduckgo/iOS/git/trees{/sha}","statuses_url":"https://api.github.com/repos/duckduckgo/iOS/statuses/{sha}","languages_url":"https://api.github.com/repos/duckduckgo/iOS/languages","stargazers_url":"https://api.github.com/repos/duckduckgo/iOS/stargazers","contributors_url":"https://api.github.com/repos/duckduckgo/iOS/contributors","subscribers_url":"https://api.github.com/repos/duckduckgo/iOS/subscribers","subscription_url":"https://api.github.com/repos/duckduckgo/iOS/subscription","commits_url":"https://api.github.com/repos/duckduckgo/iOS/commits{/sha}","git_commits_url":"https://api.github.com/repos/duckduckgo/iOS/git/commits{/sha}","comments_url":"https://api.github.com/repos/duckduckgo/iOS/comments{/number}","issue_comment_url":"https://api.github.com/repos/duckduckgo/iOS/issues/comments{/number}","contents_url":"https://api.github.com/repos/duckduckgo/iOS/contents/{+path}","compare_url":"https://api.github.com/repos/duckduckgo/iOS/compare/{base}...{head}","merges_url":"https://api.github.com/repos/duckduckgo/iOS/merges","archive_url":"https://api.github.com/repos/duckduckgo/iOS/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/duckduckgo/iOS/downloads","issues_url":"https://api.github.com/repos/duckduckgo/iOS/issues{/number}","pulls_url":"https://api.github.com/repos/duckduckgo/iOS/pulls{/number}","milestones_url":"https://api.github.com/repos/duckduckgo/iOS/milestones{/number}","notifications_url":"https://api.github.com/repos/duckduckgo/iOS/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/duckduckgo/iOS/labels{/name}","releases_url":"https://api.github.com/repos/duckduckgo/iOS/releases{/id}","deployments_url":"https://api.github.com/repos/duckduckgo/iOS/deployments","created_at":"2017-01-13T17:09:36Z","updated_at":"2018-09-04T16:23:14Z","pushed_at":"2018-09-05T09:53:16Z","git_url":"git://github.com/duckduckgo/iOS.git","ssh_url":"git@github.com:duckduckgo/iOS.git","clone_url":"https://github.com/duckduckgo/iOS.git","svn_url":"https://github.com/duckduckgo/iOS","homepage":"https://itunes.apple.com/us/app/duckduckgo-privacy-browser/id663592361?mt=8","size":15036,"stargazers_count":446,"watchers_count":446,"language":"Swift","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":65,"mirror_url":null,"archived":false,"open_issues_count":2,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":65,"open_issues":2,"watchers":446,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/duckduckgo/iOS/pulls/361"},"html":{"href":"https://github.com/duckduckgo/iOS/pull/361"},"issue":{"href":"https://api.github.com/repos/duckduckgo/iOS/issues/361"},"comments":{"href":"https://api.github.com/repos/duckduckgo/iOS/issues/361/comments"},"review_comments":{"href":"https://api.github.com/repos/duckduckgo/iOS/pulls/361/comments"},"review_comment":{"href":"https://api.github.com/repos/duckduckgo/iOS/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/duckduckgo/iOS/pulls/361/commits"},"statuses":{"href":"https://api.github.com/repos/duckduckgo/iOS/statuses/dd62a7a3e552c287dc7c2db2ef6dcd419f973ac2"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"subsymbolic"}}