{"action":"created","comment":{"url":"https://api.github.com/repos/edx/edx-app-android/pulls/comments/73464816","id":73464816,"diff_hunk":"@@ -0,0 +1,60 @@\n+package org.edx.mobile.util;\n+\n+import android.content.ActivityNotFoundException;\n+import android.content.Context;\n+import android.content.Intent;\n+import android.net.Uri;\n+import android.view.View;\n+import android.widget.Toast;\n+\n+import org.edx.mobile.BuildConfig;\n+import org.edx.mobile.R;\n+\n+/**\n+ * Utility class for interacting with an app store, or the\n+ * Play Store specifically.\n+ */\n+public final class AppStoreUtils {\n+    // Make this class non-instantiable\n+    private AppStoreUtils() {\n+        throw new UnsupportedOperationException();\n+    }\n+\n+    /**\n+     * Open an app store to display the app.\n+     *\n+     * @param context A Context for starting the new Activity.\n+     */\n+    public static void openAppInAppStore(final Context context) {\n+        Intent intent = new Intent(Intent.ACTION_VIEW);\n+        intent.addCategory(Intent.CATEGORY_BROWSABLE);\n+        intent.setData(Uri.parse(\"market://details?id=\" + BuildConfig.APPLICATION_ID));\n+        try {\n+            context.startActivity(intent);\n+        } catch (ActivityNotFoundException e) {\n+            intent.setData(Uri.parse(\"https://play.google.com/store/apps/details?id=\" +\n+                            BuildConfig.APPLICATION_ID));","path":"VideoLocker/src/main/java/org/edx/mobile/util/AppStoreUtils.java","position":null,"original_position":36,"commit_id":"efb2bf4b3469d4eab136be2c94df36c56ad1d70d","original_commit_id":"9d90db2be830287ad0c06545cb3d763c73a462cd","user":{"login":"1zaman","id":4244109,"avatar_url":"https://avatars.githubusercontent.com/u/4244109?v=3","gravatar_id":"","url":"https://api.github.com/users/1zaman","html_url":"https://github.com/1zaman","followers_url":"https://api.github.com/users/1zaman/followers","following_url":"https://api.github.com/users/1zaman/following{/other_user}","gists_url":"https://api.github.com/users/1zaman/gists{/gist_id}","starred_url":"https://api.github.com/users/1zaman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/1zaman/subscriptions","organizations_url":"https://api.github.com/users/1zaman/orgs","repos_url":"https://api.github.com/users/1zaman/repos","events_url":"https://api.github.com/users/1zaman/events{/privacy}","received_events_url":"https://api.github.com/users/1zaman/received_events","type":"User","site_admin":false},"body":"> Let's not solve for apps intercepting the `market://` URI, but lets definitely make both of these configurable.\r\n\r\nDone in commit 3e85fbcf6f164567e8885a433677caca9bd72503. The name and structure of the flags still needs to be finalized in the wiki (and then added in the existing configs), but I have tentatively assumed a `APP_UPDATE_URIS` top-level object containing `NATIVE` and `WEB` fields.\r\n\r\n> And perhaps, also have a method `boolean canOpenAppInAppStore()` that returns true if either of the URIs are configured and resolvable. And then only show the \"Update\" link if it returns true. Make sense?\r\n\r\nDone in commit 3864c8c5da4bdf984de9b495d2559179ca33d21b.","created_at":"2016-08-04T05:42:17Z","updated_at":"2016-08-04T05:42:17Z","html_url":"https://github.com/edx/edx-app-android/pull/748#discussion_r73464816","pull_request_url":"https://api.github.com/repos/edx/edx-app-android/pulls/748","_links":{"self":{"href":"https://api.github.com/repos/edx/edx-app-android/pulls/comments/73464816"},"html":{"href":"https://github.com/edx/edx-app-android/pull/748#discussion_r73464816"},"pull_request":{"href":"https://api.github.com/repos/edx/edx-app-android/pulls/748"}}},"pull_request":{"url":"https://api.github.com/repos/edx/edx-app-android/pulls/748","id":73916386,"html_url":"https://github.com/edx/edx-app-android/pull/748","diff_url":"https://github.com/edx/edx-app-android/pull/748.diff","patch_url":"https://github.com/edx/edx-app-android/pull/748.patch","issue_url":"https://api.github.com/repos/edx/edx-app-android/issues/748","number":748,"state":"open","locked":false,"title":"Implement Snackbar notifications for new releases","user":{"login":"1zaman","id":4244109,"avatar_url":"https://avatars.githubusercontent.com/u/4244109?v=3","gravatar_id":"","url":"https://api.github.com/users/1zaman","html_url":"https://github.com/1zaman","followers_url":"https://api.github.com/users/1zaman/followers","following_url":"https://api.github.com/users/1zaman/following{/other_user}","gists_url":"https://api.github.com/users/1zaman/gists{/gist_id}","starred_url":"https://api.github.com/users/1zaman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/1zaman/subscriptions","organizations_url":"https://api.github.com/users/1zaman/orgs","repos_url":"https://api.github.com/users/1zaman/repos","events_url":"https://api.github.com/users/1zaman/events{/privacy}","received_events_url":"https://api.github.com/users/1zaman/received_events","type":"User","site_admin":false},"body":"### Description\r\n\r\n[MA-1995][]\r\n\r\nAn OkHttp interceptor has been added to capture the headers notifying of new versions of the app that have been release on the app stores. These are broadcasted over the event bus and displayed on `MyCoursesListActivity` (the main dashboard Activity) [in the form of Snackbars][Version Upgrade Alerts], that will persist until the user swipes them away. The maximum limit for the number of lines in the Snackbar messages has also been raised from 2 to 10, to stop the error messages from getting truncated.\r\n\r\nThe Activity is treated as a session, with notifications not being repeated in a single session, but reset after the session is closed. This [design][notifications session proposal] is so that the notifications are always provided directly by the server, instead of being persisted on the local device. This will prevent wrongly sent headers to permanently change the app state to an incorrect one.\r\n\r\nThere are [three different notifications][Version-based App Upgrade] in descending order of priority. New notifications will only be shown if they have a higher priority than any other one that has been shown in the current session.\r\n\r\n1. Unsupported app version notifications. This is when we get a 426 (upgrade required) error as a response. This means that the API we're calling has been removed, and will no longer deliver anything.\r\n\r\n2. Deprecation notification. This is when we get notified of a new version of the app, along with a deadline after which the current version won't have it's API calls supported any longer. These are prioritized according to the closeness of their deadlines.\r\n\r\n3. New release notification. This is when we get notified of a new version of the app, without any deadline for support of the current version.  These are prioritized according to the largest new version number.\r\n\r\nApache Commons Lang 3 has been added as a new dependency, since it's `FastDateFormat` is a very useful improvement over the built-in `SimpleDateFormat`, and provides much better support for ISO 8601, which seems to be the standard used by the dates sent by the server. Specifically, the last supported date header is being sent with UTC offsets, which is part of the ISO 8601 standard, and also supported by `FastDateFormat`. All `SimpleDateFormat` usages should be replaced with `FastDateFormat` in the future.\r\n\r\nIn addition to this, some utility classes have been copied over from the Maven Artifact project in order to compare the version numbers, since we seem to following the same general versioning scheme as Maven artifacts.\r\n\r\n### Screenshots\r\n\r\nUnsupported | Deprecated | Outdated\r\n------------|------------|---------\r\n![version_unsupported][] | ![version_deprecated][] | ![version_outdated][]\r\n\r\n### Notes\r\n - This can be tested with the `temp-lahore` sandbox. Configuration can be done at https://temp-lahore.sandbox.edx.org/admin/mobile_api/appversionconfig/2.\r\n\r\n### Testing\r\n- [ ] Unit, integration, acceptance tests as appropriate\r\n\r\n### Reviewers\r\nIf you've been tagged for review, please check your corresponding box once you've given the :+1:.\r\n- [x] Code review: @miankhalid\r\n- [x] Code review: @BenjiLee\r\n- [x] Code review: @bguertin\r\n- [x] Code review: @mdinino\r\n- [x] UI strings/error msgs review: @catong\r\n- [x] UX review: @lizcohen\r\n\r\n[MA-1995]: https://openedx.atlassian.net/browse/MA-1995\r\n\r\n[Version Upgrade Alerts]: https://openedx.atlassian.net/wiki/display/MA/Version+Upgrade+Alerts\r\n[Version-based App Upgrade]: https://openedx.atlassian.net/wiki/display/MA/Version-based+App+Upgrade\r\n[notifications session proposal]: https://openedx.atlassian.net/wiki/display/MA/API+Unavailable+UX?focusedCommentId=85590017#comment-85590017\r\n\r\n[version_unsupported]: https://cloud.githubusercontent.com/assets/4244109/16081619/b9d538aa-3327-11e6-8097-4f5ab55bf17c.png\r\n[version_deprecated]: https://cloud.githubusercontent.com/assets/4244109/16081681/efc88f02-3327-11e6-9335-9e2c7e7c3be2.png\r\n[version_outdated]: https://cloud.githubusercontent.com/assets/4244109/16081747/40a7aa84-3328-11e6-9fda-a70445f8086a.png","created_at":"2016-06-15T13:58:58Z","updated_at":"2016-08-04T05:42:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"279d328c8541f19bbc30059c71f84c9e6bc5747f","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/edx/edx-app-android/pulls/748/commits","review_comments_url":"https://api.github.com/repos/edx/edx-app-android/pulls/748/comments","review_comment_url":"https://api.github.com/repos/edx/edx-app-android/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/edx-app-android/issues/748/comments","statuses_url":"https://api.github.com/repos/edx/edx-app-android/statuses/efb2bf4b3469d4eab136be2c94df36c56ad1d70d","head":{"label":"edx:MA-1995","ref":"MA-1995","sha":"efb2bf4b3469d4eab136be2c94df36c56ad1d70d","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":29251742,"name":"edx-app-android","full_name":"edx/edx-app-android","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-app-android","description":"","fork":false,"url":"https://api.github.com/repos/edx/edx-app-android","forks_url":"https://api.github.com/repos/edx/edx-app-android/forks","keys_url":"https://api.github.com/repos/edx/edx-app-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-app-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-app-android/teams","hooks_url":"https://api.github.com/repos/edx/edx-app-android/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-app-android/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-app-android/events","assignees_url":"https://api.github.com/repos/edx/edx-app-android/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-app-android/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-app-android/tags","blobs_url":"https://api.github.com/repos/edx/edx-app-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-app-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-app-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-app-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-app-android/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-app-android/languages","stargazers_url":"https://api.github.com/repos/edx/edx-app-android/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-app-android/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-app-android/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-app-android/subscription","commits_url":"https://api.github.com/repos/edx/edx-app-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-app-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-app-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-app-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-app-android/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-app-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-app-android/merges","archive_url":"https://api.github.com/repos/edx/edx-app-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-app-android/downloads","issues_url":"https://api.github.com/repos/edx/edx-app-android/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-app-android/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-app-android/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-app-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-app-android/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-app-android/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-app-android/deployments","created_at":"2015-01-14T15:49:47Z","updated_at":"2016-07-28T03:16:15Z","pushed_at":"2016-08-04T05:40:12Z","git_url":"git://github.com/edx/edx-app-android.git","ssh_url":"git@github.com:edx/edx-app-android.git","clone_url":"https://github.com/edx/edx-app-android.git","svn_url":"https://github.com/edx/edx-app-android","homepage":null,"size":23503,"stargazers_count":85,"watchers_count":85,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":94,"mirror_url":null,"open_issues_count":9,"forks":94,"open_issues":9,"watchers":85,"default_branch":"master"}},"base":{"label":"edx:master","ref":"master","sha":"b6d0b3bf560743a3aa805b9c071d905af6cad0f6","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":29251742,"name":"edx-app-android","full_name":"edx/edx-app-android","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-app-android","description":"","fork":false,"url":"https://api.github.com/repos/edx/edx-app-android","forks_url":"https://api.github.com/repos/edx/edx-app-android/forks","keys_url":"https://api.github.com/repos/edx/edx-app-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-app-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-app-android/teams","hooks_url":"https://api.github.com/repos/edx/edx-app-android/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-app-android/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-app-android/events","assignees_url":"https://api.github.com/repos/edx/edx-app-android/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-app-android/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-app-android/tags","blobs_url":"https://api.github.com/repos/edx/edx-app-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-app-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-app-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-app-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-app-android/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-app-android/languages","stargazers_url":"https://api.github.com/repos/edx/edx-app-android/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-app-android/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-app-android/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-app-android/subscription","commits_url":"https://api.github.com/repos/edx/edx-app-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-app-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-app-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-app-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-app-android/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-app-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-app-android/merges","archive_url":"https://api.github.com/repos/edx/edx-app-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-app-android/downloads","issues_url":"https://api.github.com/repos/edx/edx-app-android/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-app-android/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-app-android/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-app-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-app-android/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-app-android/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-app-android/deployments","created_at":"2015-01-14T15:49:47Z","updated_at":"2016-07-28T03:16:15Z","pushed_at":"2016-08-04T05:40:12Z","git_url":"git://github.com/edx/edx-app-android.git","ssh_url":"git@github.com:edx/edx-app-android.git","clone_url":"https://github.com/edx/edx-app-android.git","svn_url":"https://github.com/edx/edx-app-android","homepage":null,"size":23503,"stargazers_count":85,"watchers_count":85,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":94,"mirror_url":null,"open_issues_count":9,"forks":94,"open_issues":9,"watchers":85,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/edx-app-android/pulls/748"},"html":{"href":"https://github.com/edx/edx-app-android/pull/748"},"issue":{"href":"https://api.github.com/repos/edx/edx-app-android/issues/748"},"comments":{"href":"https://api.github.com/repos/edx/edx-app-android/issues/748/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/edx-app-android/pulls/748/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/edx-app-android/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/edx-app-android/pulls/748/commits"},"statuses":{"href":"https://api.github.com/repos/edx/edx-app-android/statuses/efb2bf4b3469d4eab136be2c94df36c56ad1d70d"}}}}
{"actor":{"display_login":"1zaman"}}