diff --git a/.eslintrc.json b/.eslintrc.json
index 56319633d..eb8c5c0fa 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -34,6 +34,7 @@
       "singleQuote": true
     }],
     "func-names": ["warn", "as-needed"],
-    "jsx-a11y/label-has-for": 0
+    "jsx-a11y/label-has-for": 0,
+    "import/prefer-default-export": 0
   }
 }
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 000000000..c6cc8c819
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="Eslint" enabled="true" level="ERROR" enabled_by_default="true" />
+  </profile>
+</component>
\ No newline at end of file
diff --git a/.idea/lbry-app.iml b/.idea/lbry-app.iml
new file mode 100644
index 000000000..24643cc37
--- /dev/null
+++ b/.idea/lbry-app.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
+      <excludeFolder url="file://$MODULE_DIR$/temp" />
+      <excludeFolder url="file://$MODULE_DIR$/tmp" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 000000000..3668dc8ca
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="FLOW" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 000000000..b37b46a86
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/lbry-app.iml" filepath="$PROJECT_DIR$/.idea/lbry-app.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 000000000..94a25f7f4
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 000000000..a51b0ec12
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,547 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="061e089e-71dc-4d6b-b27c-9c614b097257" name="Default" comment="">
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/renderer/types/claim.js" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/component/fileDetails/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/component/fileDetails/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/component/uriIndicator/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/component/uriIndicator/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/component/video/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/component/video/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/component/walletSendTip/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/component/walletSendTip/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/page/channel/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/page/channel/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/page/file/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/page/file/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/page/show/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/page/show/view.jsx" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/renderer/page/subscriptions/view.jsx" afterPath="$PROJECT_DIR$/src/renderer/page/subscriptions/view.jsx" />
+    </list>
+    <ignored path="$PROJECT_DIR$/.tmp/" />
+    <ignored path="$PROJECT_DIR$/temp/" />
+    <ignored path="$PROJECT_DIR$/tmp/" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
+      <file leaf-file-name="view.jsx" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="0">
+              <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+              <folding>
+                <element signature="e#0#26#0" expanded="true" />
+                <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="index.js" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="216">
+              <caret line="12" column="0" lean-forward="false" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
+              <folding>
+                <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="package.json" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/package.json">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="1332">
+              <caret line="74" column="0" lean-forward="false" selection-start-line="74" selection-start-column="0" selection-end-line="74" selection-end-column="0" />
+              <folding>
+                <marker date="1526397284183" expanded="true" signature="2668:3140" ph="{&quot;axios&quot;: &quot;^0.18.0&quot;...}" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="join.js" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/node_modules/bluebird/js/release/join.js">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="144">
+              <caret line="8" column="11" lean-forward="false" selection-start-line="8" selection-start-column="11" selection-end-line="8" selection-end-column="11" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="view.jsx" pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/src/renderer/page/file/view.jsx">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="287">
+              <caret line="18" column="15" lean-forward="false" selection-start-line="18" selection-start-column="14" selection-end-line="18" selection-end-column="15" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="FindInProjectRecents">
+    <findStrings>
+      <find>TYPE_FEATURED_DOWNLOAD</find>
+      <find>TYPE_FEATURED_DOW</find>
+      <find>doOpen</find>
+      <find>doNotify</find>
+      <find>settings</find>
+    </findStrings>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="IdeDocumentHistory">
+    <option name="CHANGED_PATHS">
+      <list>
+        <option value="$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js" />
+        <option value="$PROJECT_DIR$/package.json" />
+        <option value="$PROJECT_DIR$/README.md" />
+        <option value="$PROJECT_DIR$/src/renderer/page/file/view.jsx" />
+      </list>
+    </option>
+  </component>
+  <component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
+  <component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER">
+    <package-json value="$PROJECT_DIR$/package.json" />
+  </component>
+  <component name="JsFlowSettings">
+    <service-enabled>true</service-enabled>
+    <exe-path />
+    <annotation-enable>false</annotation-enable>
+    <other-services-enabled>true</other-services-enabled>
+    <auto-save>true</auto-save>
+  </component>
+  <component name="JsGulpfileManager">
+    <detection-done>true</detection-done>
+    <sorting>DEFINITION_ORDER</sorting>
+  </component>
+  <component name="NodeModulesDirectoryManager">
+    <handled-path value="$PROJECT_DIR$/dist/linux-unpacked/resources/app.asar.unpacked/node_modules" />
+    <handled-path value="$PROJECT_DIR$/node_modules" />
+  </component>
+  <component name="PhpWorkspaceProjectConfiguration" backward_compatibility_performed="true" />
+  <component name="ProjectFrameBounds" extendedState="6">
+    <option name="y" value="24" />
+    <option name="width" value="1920" />
+    <option name="height" value="1056" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="Scope" />
+      <pane id="ProjectPane">
+        <subPane>
+          <expand>
+            <path>
+              <item name="lbry-app" type="b2602c69:ProjectViewProjectNode" />
+              <item name="lbry-app" type="2a2b976b:PhpTreeStructureProvider$1" />
+            </path>
+          </expand>
+          <select />
+        </subPane>
+      </pane>
+      <pane id="Scratches" />
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="WebServerToolWindowFactoryState" value="false" />
+    <property name="nodejs_interpreter_path" value="/usr/local/bin/node" />
+    <property name="HbShouldOpenHtmlAsHb" value="" />
+    <property name="node.js.path.for.package.eslint" value="project" />
+    <property name="node.js.detected.package.eslint" value="true" />
+    <property name="node.js.selected.package.eslint" value="$PROJECT_DIR$/node_modules/eslint" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+  </component>
+  <component name="RunDashboard">
+    <option name="ruleStates">
+      <list>
+        <RuleState>
+          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+        </RuleState>
+        <RuleState>
+          <option name="name" value="StatusDashboardGroupingRule" />
+        </RuleState>
+      </list>
+    </option>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false">
+    <option name="remove_strategy" value="false" />
+  </component>
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="061e089e-71dc-4d6b-b27c-9c614b097257" name="Default" comment="" />
+      <created>1522354295512</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1522354295512</updated>
+      <workItem from="1522354299246" duration="1866000" />
+      <workItem from="1522643117648" duration="2000" />
+      <workItem from="1524064618567" duration="2674000" />
+      <workItem from="1525381677126" duration="197000" />
+      <workItem from="1525382363305" duration="597000" />
+      <workItem from="1525461458836" duration="70000" />
+      <workItem from="1526067492327" duration="897000" />
+      <workItem from="1526397339713" duration="27000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TimeTrackingManager">
+    <option name="totallyTimeSpent" value="6330000" />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="0" y="24" width="1920" height="1055" extended-state="6" />
+    <editor active="true" />
+    <layout>
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="npm" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="1" />
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager />
+    <watches-manager />
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="216">
+          <caret line="12" column="0" lean-forward="false" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/package.json">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1332">
+          <caret line="74" column="0" lean-forward="false" selection-start-line="74" selection-start-column="0" selection-end-line="74" selection-end-column="0" />
+          <folding>
+            <marker date="1526397284183" expanded="true" signature="2668:3140" ph="{&quot;axios&quot;: &quot;^0.18.0&quot;...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/node_modules/bluebird/js/release/join.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="144">
+          <caret line="8" column="11" lean-forward="false" selection-start-line="8" selection-start-column="11" selection-end-line="8" selection-end-column="11" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/package.json">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1332">
+          <caret line="74" column="0" lean-forward="false" selection-start-line="74" selection-start-column="0" selection-end-line="74" selection-end-column="0" />
+          <folding>
+            <marker date="1526397284183" expanded="true" signature="2668:3140" ph="{&quot;axios&quot;: &quot;^0.18.0&quot;...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="216">
+          <caret line="12" column="0" lean-forward="false" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/node_modules/bluebird/js/release/join.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="216">
+          <caret line="12" column="0" lean-forward="false" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/package.json">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="2322">
+          <caret line="129" column="38" lean-forward="false" selection-start-line="129" selection-start-column="38" selection-end-line="129" selection-end-column="38" />
+          <folding>
+            <marker date="1526397284183" expanded="true" signature="2668:3140" ph="{&quot;axios&quot;: &quot;^0.18.0&quot;...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="144">
+          <caret line="19" column="68" lean-forward="true" selection-start-line="19" selection-start-column="68" selection-end-line="19" selection-end-column="68" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/page/rewards/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-122">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/redux/reducers/rewards.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-28">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/redux/actions/rewards.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-832">
+          <caret line="13" column="61" lean-forward="false" selection-start-line="13" selection-start-column="36" selection-end-line="13" selection-end-column="61" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/rewards.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="324">
+          <caret line="18" column="0" lean-forward="false" selection-start-line="18" selection-start-column="0" selection-end-line="18" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="216">
+          <caret line="12" column="0" lean-forward="false" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/package.json">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="693">
+          <caret line="129" column="38" lean-forward="false" selection-start-line="129" selection-start-column="38" selection-end-line="129" selection-end-column="38" />
+          <folding>
+            <marker date="1526397284183" expanded="true" signature="2668:3140" ph="{&quot;axios&quot;: &quot;^0.18.0&quot;...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="144">
+          <caret line="19" column="68" lean-forward="true" selection-start-line="19" selection-start-column="68" selection-end-line="19" selection-end-column="68" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/page/rewards/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-122">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/redux/reducers/rewards.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-28">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/redux/actions/rewards.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-832">
+          <caret line="13" column="61" lean-forward="false" selection-start-line="13" selection-start-column="36" selection-end-line="13" selection-end-column="61" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/rewards.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="324">
+          <caret line="18" column="0" lean-forward="false" selection-start-line="18" selection-start-column="0" selection-end-line="18" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="e#0#26#0" expanded="true" />
+            <marker date="1526068149928" expanded="true" signature="5366:5471" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/modal/modalRouter/index.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="216">
+          <caret line="12" column="0" lean-forward="false" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
+          <folding>
+            <marker date="1525123536618" expanded="true" signature="1172:1177" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/package.json">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1332">
+          <caret line="74" column="0" lean-forward="false" selection-start-line="74" selection-start-column="0" selection-end-line="74" selection-end-column="0" />
+          <folding>
+            <marker date="1526397284183" expanded="true" signature="2668:3140" ph="{&quot;axios&quot;: &quot;^0.18.0&quot;...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/CONTRIBUTING.md">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="540">
+          <caret line="168" column="0" lean-forward="true" selection-start-line="168" selection-start-column="0" selection-end-line="168" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/README.md">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="846">
+          <caret line="47" column="81" lean-forward="true" selection-start-line="47" selection-start-column="81" selection-end-line="47" selection-end-column="81" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/node_modules/bluebird/js/release/join.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="144">
+          <caret line="8" column="11" lean-forward="false" selection-start-line="8" selection-start-column="11" selection-end-line="8" selection-end-column="11" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/renderer/page/file/view.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="287">
+          <caret line="18" column="15" lean-forward="false" selection-start-line="18" selection-start-column="14" selection-end-line="18" selection-end-column="15" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+  </component>
+</project>
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d31dbbc93..f00467470 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
 ### Changed
    * Add flair to snackbar ([#1313](https://github.com/lbryio/lbry-app/pull/1313))
    * Made font in price badge larger ([#1420](https://github.com/lbryio/lbry-app/pull/1420))
+   * Store subscriptions in internal database ([#1424](https://github.com/lbryio/lbry-app/pull/1424))
 
 ### Fixed
    * Fix content-type not shown correctly in file description ([#863](https://github.com/lbryio/lbry-app/pull/863))
diff --git a/src/renderer/analytics.js b/src/renderer/analytics.js
index 2a03b7428..a4fd24258 100644
--- a/src/renderer/analytics.js
+++ b/src/renderer/analytics.js
@@ -2,7 +2,6 @@
 import mixpanel from 'mixpanel-browser';
 import Lbryio from 'lbryio';
 import isDev from 'electron-is-dev';
-import type { Subscription } from 'redux/reducers/subscriptions';
 
 if (isDev) {
   mixpanel.init('691723e855cabb9d27a7a79002216967');
@@ -15,8 +14,6 @@ type Analytics = {
   setUser: Object => void,
   toggle: (boolean, ?boolean) => void,
   apiLogView: (string, string, string) => void,
-  apiLogSubscribe: Subscription => void,
-  apiLogUnsubscribe: Subscription => void,
 };
 
 let analyticsEnabled: boolean = false;
@@ -56,20 +53,6 @@ const analytics: Analytics = {
       }).catch(() => {});
     }
   },
-  apiLogSubscribe: (subscription: Subscription): void => {
-    if (analyticsEnabled) {
-      Lbryio.call('subscription', 'new', {
-        subscription,
-      }).catch(() => {});
-    }
-  },
-  apiLogUnsubscribe: (subscription: Subscription): void => {
-    if (analyticsEnabled) {
-      Lbryio.call('subscription', 'delete', {
-        subscription,
-      }).catch(() => {});
-    }
-  },
 };
 
 export default analytics;
diff --git a/src/renderer/component/common/spinner.jsx b/src/renderer/component/common/spinner.jsx
index 7ba514607..e69de29bb 100644
--- a/src/renderer/component/common/spinner.jsx
+++ b/src/renderer/component/common/spinner.jsx
@@ -1,28 +0,0 @@
-// @flow
-import * as React from 'react';
-import classnames from 'classnames';
-
-type Props = {
-  dark?: boolean,
-};
-
-class Spinner extends React.Component<Props> {
-  static defaultProps = {
-    dark: false,
-  };
-
-  render() {
-    const { dark } = this.props;
-    return (
-      <div className={classnames('spinner', { 'spinner--dark': dark })}>
-        <div className="rect rect1" />
-        <div className="rect rect2" />
-        <div className="rect rect3" />
-        <div className="rect rect4" />
-        <div className="rect rect5" />
-      </div>
-    );
-  }
-}
-
-export default Spinner;
diff --git a/src/renderer/component/fileDetails/view.jsx b/src/renderer/component/fileDetails/view.jsx
index e49af3417..c793d25ef 100644
--- a/src/renderer/component/fileDetails/view.jsx
+++ b/src/renderer/component/fileDetails/view.jsx
@@ -3,9 +3,10 @@ import * as React from 'react';
 import ReactMarkdown from 'react-markdown';
 import Button from 'component/button';
 import path from 'path';
+import type { Claim } from 'types/claim';
 
 type Props = {
-  claim: {},
+  claim: Claim,
   fileInfo: {
     download_path: string,
   },
diff --git a/src/renderer/component/fileList/view.jsx b/src/renderer/component/fileList/view.jsx
index ffe8ecbff..8bc26d362 100644
--- a/src/renderer/component/fileList/view.jsx
+++ b/src/renderer/component/fileList/view.jsx
@@ -53,7 +53,6 @@ class FileList extends React.PureComponent<Props, State> {
               if (fileInfo1.pending) {
                 return -1;
               }
-
               const height1 = this.props.claimsById[fileInfo1.claim_id]
                 ? this.props.claimsById[fileInfo1.claim_id].height
                 : 0;
@@ -145,6 +144,10 @@ class FileList extends React.PureComponent<Props, State> {
     const { sortBy } = this.state;
     const content = [];
 
+    if (!fileInfos) {
+      return null;
+    }
+
     this.sortFunctions[sortBy](fileInfos).forEach(fileInfo => {
       const {
         channel_name: channelName,
diff --git a/src/renderer/component/page/view.jsx b/src/renderer/component/page/view.jsx
index 40ec8564b..9af308b79 100644
--- a/src/renderer/component/page/view.jsx
+++ b/src/renderer/component/page/view.jsx
@@ -1,33 +1,98 @@
 // @flow
 import * as React from 'react';
 import classnames from 'classnames';
+import Spinner from 'component/spinner';
+import { isShowingChildren } from 'util/dom';
+
+// time in ms to wait to show loading spinner
+const LOADER_TIMEOUT = 1500;
 
 type Props = {
-  children: React.Node,
+  children: React.Node | Array<React.Node>,
   pageTitle: ?string,
   noPadding: ?boolean,
   extraPadding: ?boolean,
   notContained: ?boolean, // No max-width, but keep the padding
+  loading: ?boolean,
 };
 
-const Page = (props: Props) => {
-  const { pageTitle, children, noPadding, extraPadding, notContained } = props;
-  return (
-    <main
-      className={classnames('main', {
-        'main--contained': !notContained && !noPadding && !extraPadding,
-        'main--no-padding': noPadding,
-        'main--extra-padding': extraPadding,
-      })}
-    >
-      {pageTitle && (
-        <div className="page__header">
-          {pageTitle && <h1 className="page__title">{pageTitle}</h1>}
-        </div>
-      )}
-      {children}
-    </main>
-  );
+type State = {
+  showLoader: ?boolean,
 };
 
+class Page extends React.PureComponent<Props, State> {
+  static getDerivedStateFromProps(nextProps: Props, prevState: State) {
+    const { children } = nextProps;
+    const { showLoader } = prevState;
+
+    // If we aren't showing the loader, don't bother updating
+    if (!showLoader) {
+      return null;
+    }
+
+    if (isShowingChildren(children)) {
+      return {
+        showLoader: false,
+      };
+    }
+    return null;
+  }
+
+  constructor() {
+    super();
+
+    this.state = {
+      showLoader: false,
+    };
+
+    this.loaderTimeout = null;
+  }
+
+  componentDidMount() {
+    const { children } = this.props;
+
+    if (!isShowingChildren(children))
+      this.loaderTimeout = setTimeout(() => {
+        this.setState({ showLoader: true });
+      }, LOADER_TIMEOUT);
+  }
+
+  componentWillUnmount() {
+    this.loaderTimeout = null;
+  }
+
+  loaderTimeout: ?TimeoutID;
+
+  render() {
+    const { pageTitle, children, noPadding, extraPadding, notContained, loading } = this.props;
+    const { showLoader } = this.state;
+
+    // We don't want to show the loading spinner right away if it will only flash on the
+    // screen for a short time, wait until we know it will be loading for a bit before showing it
+    const shouldShowLoader = !isShowingChildren(children) && showLoader;
+
+    return (
+      <main
+        className={classnames('main', {
+          'main--contained': !notContained && !noPadding && !extraPadding,
+          'main--no-padding': noPadding,
+          'main--extra-padding': extraPadding,
+        })}
+      >
+        {pageTitle && (
+          <div className="page__header">
+            {pageTitle && <h1 className="page__title">{pageTitle}</h1>}
+          </div>
+        )}
+        {!loading && children}
+        {shouldShowLoader && (
+          <div className="page__empty">
+            <Spinner />
+          </div>
+        )}
+      </main>
+    );
+  }
+}
+
 export default Page;
diff --git a/src/renderer/component/spinner/index.js b/src/renderer/component/spinner/index.js
new file mode 100644
index 000000000..6589e05da
--- /dev/null
+++ b/src/renderer/component/spinner/index.js
@@ -0,0 +1,9 @@
+import { connect } from 'react-redux';
+import { selectTheme } from 'redux/selectors/settings';
+import Spinner from './view';
+
+const mapStateToProps = state => ({
+  theme: selectTheme(state),
+});
+
+export default connect(mapStateToProps, null)(Spinner);
diff --git a/src/renderer/component/spinner/view.jsx b/src/renderer/component/spinner/view.jsx
new file mode 100644
index 000000000..bb44ee6f7
--- /dev/null
+++ b/src/renderer/component/spinner/view.jsx
@@ -0,0 +1,36 @@
+// @flow
+import * as React from 'react';
+import classnames from 'classnames';
+import { DARK_THEME, LIGHT_THEME } from 'constants/themes';
+
+type Props = {
+  dark?: boolean, // always a dark spinner
+  light?: boolean, // always a light spinner
+  theme: string,
+};
+
+const Spinner = (props: Props) => {
+  const { dark, light, theme } = props;
+
+  return (
+    <div
+      className={classnames('spinner', {
+        'spinner--dark': !light && (dark || theme === LIGHT_THEME),
+        'spinner--light': !dark && (light || theme === DARK_THEME),
+      })}
+    >
+      <div className="rect rect1" />
+      <div className="rect rect2" />
+      <div className="rect rect3" />
+      <div className="rect rect4" />
+      <div className="rect rect5" />
+    </div>
+  );
+};
+
+Spinner.defaultProps = {
+  dark: false,
+  light: false,
+};
+
+export default Spinner;
diff --git a/src/renderer/component/subscribeButton/view.jsx b/src/renderer/component/subscribeButton/view.jsx
index 1a341447f..52516dfb8 100644
--- a/src/renderer/component/subscribeButton/view.jsx
+++ b/src/renderer/component/subscribeButton/view.jsx
@@ -3,7 +3,7 @@ import React from 'react';
 import { MODALS } from 'lbry-redux';
 import * as icons from 'constants/icons';
 import Button from 'component/button';
-import type { Subscription } from 'redux/reducers/subscriptions';
+import type { Subscription } from 'types/subscription';
 
 type SubscribtionArgs = {
   channelName: string,
diff --git a/src/renderer/component/uriIndicator/view.jsx b/src/renderer/component/uriIndicator/view.jsx
index 499b11fba..98c249932 100644
--- a/src/renderer/component/uriIndicator/view.jsx
+++ b/src/renderer/component/uriIndicator/view.jsx
@@ -3,21 +3,18 @@ import React from 'react';
 import Button from 'component/button';
 import { buildURI } from 'lbry-redux';
 import classnames from 'classnames';
-// import Icon from 'component/common/icon';
+import type { Claim } from 'types/claim';
 
 type Props = {
   isResolvingUri: boolean,
-  resolveUri: string => void,
-  claim: {
-    channel_name: string,
-    has_signature: boolean,
-    signature_is_valid: boolean,
-    value: {
-      publisherSignature: { certificateId: string },
-    },
-  },
-  uri: string,
+  claim: Claim,
   link: ?boolean,
+  // Lint thinks we aren't using these, even though we are.
+  // Possibly because the resolve function is an arrow function that is passed in props?
+  /* eslint-disable react/no-unused-prop-types */
+  resolveUri: string => void,
+  uri: string,
+  /* eslint-enable react/no-unused-prop-types */
 };
 
 class UriIndicator extends React.PureComponent<Props> {
diff --git a/src/renderer/component/video/internal/loading-screen.jsx b/src/renderer/component/video/internal/loading-screen.jsx
index ccada9d41..f313b412d 100644
--- a/src/renderer/component/video/internal/loading-screen.jsx
+++ b/src/renderer/component/video/internal/loading-screen.jsx
@@ -1,6 +1,6 @@
 // @flow
 import React from 'react';
-import Spinner from 'component/common/spinner';
+import Spinner from 'component/spinner';
 
 type Props = {
   spinner: boolean,
@@ -16,7 +16,7 @@ class LoadingScreen extends React.PureComponent<Props> {
     const { status, spinner } = this.props;
     return (
       <div className="content__loading">
-        {spinner && <Spinner />}
+        {spinner && <Spinner light />}
 
         <span className="content__loading-text">{status}</span>
       </div>
diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx
index c1663c5e3..761a19e10 100644
--- a/src/renderer/component/video/view.jsx
+++ b/src/renderer/component/video/view.jsx
@@ -2,6 +2,7 @@
 import React from 'react';
 import { Lbry } from 'lbry-redux';
 import classnames from 'classnames';
+import type { Claim } from 'types/claim';
 import VideoPlayer from './internal/player';
 import VideoPlayButton from './internal/play-button';
 import LoadingScreen from './internal/loading-screen';
@@ -26,7 +27,7 @@ type Props = {
   contentType: string,
   changeVolume: number => void,
   volume: number,
-  claim: {},
+  claim: Claim,
   uri: string,
   doPlay: () => void,
   doPause: () => void,
diff --git a/src/renderer/component/walletSendTip/view.jsx b/src/renderer/component/walletSendTip/view.jsx
index 9af0da866..a8d10a8a5 100644
--- a/src/renderer/component/walletSendTip/view.jsx
+++ b/src/renderer/component/walletSendTip/view.jsx
@@ -3,11 +3,12 @@ import React from 'react';
 import Button from 'component/button';
 import { FormField } from 'component/common/form';
 import UriIndicator from 'component/uriIndicator';
+import type { Claim } from 'types/claim';
 
 type Props = {
   uri: string,
   title: string,
-  claim: { claim_id: string },
+  claim: Claim,
   errorMessage: string,
   isPending: boolean,
   sendSupport: (number, string, string) => void,
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js
index 27678804b..3ffe23e6e 100644
--- a/src/renderer/constants/action_types.js
+++ b/src/renderer/constants/action_types.js
@@ -1,3 +1,13 @@
+/*
+  Constants for redux actions
+  All names should be in present tense
+  ex:
+  XXX_START
+  XXX_SUCCESS
+  XXX_FAIL
+  XXX_COMPLETE // if there is no fail case
+*/
+
 export const WINDOW_FOCUSED = 'WINDOW_FOCUSED';
 export const DAEMON_READY = 'DAEMON_READY';
 export const DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH';
@@ -166,6 +176,9 @@ export const SET_SUBSCRIPTION_NOTIFICATIONS = 'SET_SUBSCRIPTION_NOTIFICATIONS';
 export const CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED';
 export const CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED';
 export const CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE';
+export const FETCH_SUBSCRIPTIONS_START = 'FETCH_SUBSCRIPTIONS_START';
+export const FETCH_SUBSCRIPTIONS_FAIL = 'FETCH_SUBSCRIPTIONS_FAIL';
+export const FETCH_SUBSCRIPTIONS_SUCCESS = 'FETCH_SUBSCRIPTIONS_SUCCESS';
 
 // Video controls
 export const SET_VIDEO_PAUSE = 'SET_VIDEO_PAUSE';
diff --git a/src/renderer/constants/themes.js b/src/renderer/constants/themes.js
new file mode 100644
index 000000000..0b9cc53b6
--- /dev/null
+++ b/src/renderer/constants/themes.js
@@ -0,0 +1,4 @@
+// css theme values
+// saved in settings and found at /static/themes/{theme}.css
+export const DARK_THEME = 'dark';
+export const LIGHT_THEME = 'light';
diff --git a/src/renderer/page/channel/view.jsx b/src/renderer/page/channel/view.jsx
index 59a5b5531..693cb3c89 100644
--- a/src/renderer/page/channel/view.jsx
+++ b/src/renderer/page/channel/view.jsx
@@ -6,6 +6,7 @@ import ReactPaginate from 'react-paginate';
 import SubscribeButton from 'component/subscribeButton';
 import Page from 'component/page';
 import FileList from 'component/fileList';
+import type { Claim } from 'types/claim';
 
 type Props = {
   uri: string,
@@ -13,10 +14,7 @@ type Props = {
   totalPages: number,
   fetching: boolean,
   params: { page: number },
-  claim: {
-    name: string,
-    claim_id: string,
-  },
+  claim: Claim,
   claimsInChannel: Array<{}>,
   fetchClaims: (string, number) => void,
   fetchClaimCount: string => void,
@@ -58,8 +56,8 @@ class ChannelPage extends React.PureComponent<Props> {
   }
 
   render() {
-    const { fetching, claimsInChannel, claim, uri, page, totalPages } = this.props;
-    const { name } = claim;
+    const { fetching, claimsInChannel, claim, page, totalPages } = this.props;
+    const { name, permanent_url: permanentUrl } = claim;
 
     let contentList;
     if (fetching) {
@@ -78,7 +76,7 @@ class ChannelPage extends React.PureComponent<Props> {
         <section className="card__channel-info card__channel-info--large">
           <h1>{name}</h1>
           <div className="card__actions card__actions--no-margin">
-            <SubscribeButton uri={uri} channelName={name} />
+            <SubscribeButton uri={permanentUrl} channelName={name} />
           </div>
         </section>
         <section>{contentList}</section>
diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx
index 40cc010a2..bf7c34846 100644
--- a/src/renderer/page/file/view.jsx
+++ b/src/renderer/page/file/view.jsx
@@ -16,18 +16,10 @@ import SubscribeButton from 'component/subscribeButton';
 import Page from 'component/page';
 import player from 'render-media';
 import * as settings from 'constants/settings';
+import type { Claim } from 'types/claim';
 
 type Props = {
-  claim: {
-    claim_id: string,
-    height: number,
-    channel_name: string,
-    value: {
-      publisherSignature: ?{
-        certificateId: ?string,
-      },
-    },
-  },
+  claim: Claim,
   fileInfo: {},
   metadata: {
     title: string,
diff --git a/src/renderer/page/show/view.jsx b/src/renderer/page/show/view.jsx
index aa6e042ad..afa753be6 100644
--- a/src/renderer/page/show/view.jsx
+++ b/src/renderer/page/show/view.jsx
@@ -5,16 +5,13 @@ import ChannelPage from 'page/channel';
 import FilePage from 'page/file';
 import Page from 'component/page';
 import Button from 'component/button';
+import type { Claim } from 'types/claim';
 
 type Props = {
   isResolvingUri: boolean,
   resolveUri: string => void,
   uri: string,
-  claim: {
-    name: string,
-    txid: string,
-    nout: number,
-  },
+  claim: Claim,
   blackListedOutpoints: Array<{
     txid: string,
     nout: number,
diff --git a/src/renderer/page/subscriptions/index.js b/src/renderer/page/subscriptions/index.js
index 4d1ce6409..433adc80c 100644
--- a/src/renderer/page/subscriptions/index.js
+++ b/src/renderer/page/subscriptions/index.js
@@ -1,27 +1,25 @@
-import React from 'react';
 import { connect } from 'react-redux';
 import {
-  selectSubscriptionsFromClaims,
+  selectSubscriptionClaims,
   selectSubscriptions,
-  selectHasFetchedSubscriptions,
+  selectSubscriptionsBeingFetched,
+  selectIsFetchingSubscriptions,
   selectNotifications,
 } from 'redux/selectors/subscriptions';
 import { doFetchClaimsByChannel } from 'redux/actions/content';
-import {
-  setHasFetchedSubscriptions,
-  setSubscriptionNotifications,
-} from 'redux/actions/subscriptions';
+import { setSubscriptionNotifications, doFetchMySubscriptions } from 'redux/actions/subscriptions';
 import SubscriptionsPage from './view';
 
 const select = state => ({
-  hasFetchedSubscriptions: state.subscriptions.hasFetchedSubscriptions,
-  savedSubscriptions: selectSubscriptions(state),
-  subscriptions: selectSubscriptionsFromClaims(state),
+  isFetchingSubscriptions: selectIsFetchingSubscriptions(state),
+  subscriptionsBeingFetched: selectSubscriptionsBeingFetched(state),
+  subscriptions: selectSubscriptions(state),
+  subscriptionClaims: selectSubscriptionClaims(state),
   notifications: selectNotifications(state),
 });
 
 export default connect(select, {
   doFetchClaimsByChannel,
-  setHasFetchedSubscriptions,
   setSubscriptionNotifications,
+  doFetchMySubscriptions,
 })(SubscriptionsPage);
diff --git a/src/renderer/page/subscriptions/view.jsx b/src/renderer/page/subscriptions/view.jsx
index 27f3fac45..1ea53e306 100644
--- a/src/renderer/page/subscriptions/view.jsx
+++ b/src/renderer/page/subscriptions/view.jsx
@@ -1,39 +1,28 @@
 // @flow
 import React from 'react';
 import Page from 'component/page';
-import CategoryList from 'component/common/category-list';
-import type { Subscription } from 'redux/reducers/subscriptions';
+import type { Subscription } from 'types/subscription';
 import * as NOTIFICATION_TYPES from 'constants/notification_types';
 import Button from 'component/button';
-
-type SavedSubscriptions = Array<Subscription>;
+import FileList from 'component/fileList';
+import type { Claim } from 'types/claim';
 
 type Props = {
-  doFetchClaimsByChannel: (string, number) => any,
-  savedSubscriptions: SavedSubscriptions,
-  // TODO build out claim types
-  subscriptions: Array<any>,
-  setHasFetchedSubscriptions: () => void,
-  hasFetchedSubscriptions: boolean,
+  doFetchClaimsByChannel: (string, number) => void,
+  doFetchMySubscriptions: () => void,
+  setSubscriptionNotifications: ({}) => void,
+  subscriptions: Array<Subscription>,
+  isFetchingSubscriptions: boolean,
+  subscriptionClaims: Array<{ uri: string, claims: Array<Claim> }>,
+  subscriptionsBeingFetched: {},
+  notifications: {},
 };
 
 export default class extends React.PureComponent<Props> {
-  // setHasFetchedSubscriptions is a terrible hack
-  // it allows the subscriptions to load correctly when refresing on the subscriptions page
-  // currently the page is rendered before the state is rehyrdated
-  // that causes this component to be rendered with zero savedSubscriptions
-  // we need to wait until persist/REHYDRATE has fired before rendering the page
   componentDidMount() {
-    const {
-      savedSubscriptions,
-      setHasFetchedSubscriptions,
-      notifications,
-      setSubscriptionNotifications,
-    } = this.props;
-    if (savedSubscriptions.length) {
-      this.fetchSubscriptions(savedSubscriptions);
-      setHasFetchedSubscriptions();
-    }
+    const { notifications, setSubscriptionNotifications, doFetchMySubscriptions } = this.props;
+    doFetchMySubscriptions();
+
     const newNotifications = {};
     Object.keys(notifications).forEach(cur => {
       if (notifications[cur].type === NOTIFICATION_TYPES.DOWNLOADING) {
@@ -43,40 +32,37 @@ export default class extends React.PureComponent<Props> {
     setSubscriptionNotifications(newNotifications);
   }
 
-  componentWillReceiveProps(props: Props) {
-    const { savedSubscriptions, hasFetchedSubscriptions, setHasFetchedSubscriptions } = props;
+  componentDidUpdate() {
+    const {
+      subscriptions,
+      subscriptionClaims,
+      doFetchClaimsByChannel,
+      subscriptionsBeingFetched,
+    } = this.props;
 
-    if (!hasFetchedSubscriptions && savedSubscriptions.length) {
-      this.fetchSubscriptions(savedSubscriptions);
-      setHasFetchedSubscriptions();
-    }
-  }
+    const subscriptionClaimMap = {};
+    subscriptionClaims.forEach(claim => {
+      subscriptionClaimMap[claim.uri] = 1;
+    });
 
-  fetchSubscriptions(savedSubscriptions: SavedSubscriptions) {
-    const { doFetchClaimsByChannel } = this.props;
-    if (savedSubscriptions.length) {
-      // can this use batchActions?
-      savedSubscriptions.forEach(sub => {
+    subscriptions.forEach(sub => {
+      if (!subscriptionClaimMap[sub.uri] && !subscriptionsBeingFetched[sub.uri]) {
         doFetchClaimsByChannel(sub.uri, 1);
-      });
-    }
+      }
+    });
   }
 
   render() {
-    const { subscriptions, savedSubscriptions } = this.props;
+    const { subscriptions, subscriptionClaims, isFetchingSubscriptions } = this.props;
 
-    // TODO: if you are subscribed to an empty channel, this will always be true (but it should not be)
-    const someClaimsNotLoaded = Boolean(
-      subscriptions.find(subscription => !subscription.claims.length)
-    );
-
-    const fetchingSubscriptions =
-      !!savedSubscriptions.length &&
-      (subscriptions.length !== savedSubscriptions.length || someClaimsNotLoaded);
+    let claimList = [];
+    subscriptionClaims.forEach(claimData => {
+      claimList = claimList.concat(claimData.claims);
+    });
 
     return (
-      <Page noPadding isLoading={fetchingSubscriptions}>
-        {!savedSubscriptions.length && (
+      <Page notContained loading={isFetchingSubscriptions}>
+        {!subscriptions.length && (
           <div className="page__empty">
             {__("It looks like you aren't subscribed to any channels yet.")}
             <div className="card__actions card__actions--center">
@@ -84,28 +70,7 @@ export default class extends React.PureComponent<Props> {
             </div>
           </div>
         )}
-        {!!savedSubscriptions.length && (
-          <div>
-            {!!subscriptions.length &&
-              subscriptions.map(subscription => {
-                if (!subscription.claims.length) {
-                  // will need to update when you can subscribe to empty channels
-                  // for now this prevents issues with FeaturedCategory being rendered
-                  // before the names (claim uris) are populated
-                  return '';
-                }
-
-                return (
-                  <CategoryList
-                    key={subscription.channelName}
-                    categoryLink={subscription.uri}
-                    category={subscription.channelName}
-                    names={subscription.claims}
-                  />
-                );
-              })}
-          </div>
-        )}
+        {!!claimList.length && <FileList hideFilter sortByHeight fileInfos={claimList} />}
       </Page>
     );
   }
diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js
index 1ae851565..8dae86f8f 100644
--- a/src/renderer/redux/actions/content.js
+++ b/src/renderer/redux/actions/content.js
@@ -138,6 +138,7 @@ export function doUpdateLoadStatus(uri, outpoint) {
                 : acc,
             0
           );
+
           const notif = new window.Notification(notifications[uri].subscription.channelName, {
             body: `Posted ${fileInfo.metadata.title}${
               count > 1 && count < 10 ? ` and ${count - 1} other new items` : ''
diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js
index 6f0dba49f..b98e7b7a5 100644
--- a/src/renderer/redux/actions/subscriptions.js
+++ b/src/renderer/redux/actions/subscriptions.js
@@ -2,56 +2,127 @@
 import * as ACTIONS from 'constants/action_types';
 import * as NOTIFICATION_TYPES from 'constants/notification_types';
 import type {
-  Subscription,
   Dispatch,
   SubscriptionState,
   SubscriptionNotifications,
 } from 'redux/reducers/subscriptions';
+import type { Subscription } from 'types/subscription';
 import { selectSubscriptions } from 'redux/selectors/subscriptions';
-import { Lbry, buildURI } from 'lbry-redux';
+import { Lbry, buildURI, parseURI } from 'lbry-redux';
 import { doPurchaseUri } from 'redux/actions/content';
-import { doNavigate } from 'redux/actions/navigation';
-import analytics from 'analytics';
+import Promise from 'bluebird';
+import Lbryio from 'lbryio';
 
 const CHECK_SUBSCRIPTIONS_INTERVAL = 60 * 60 * 1000;
 const SUBSCRIPTION_DOWNLOAD_LIMIT = 1;
 
-export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch) => {
-  dispatch({
-    type: ACTIONS.CHANNEL_SUBSCRIBE,
-    data: subscription,
-  });
+export const doFetchMySubscriptions = () => (dispatch: Dispatch, getState: () => any) => {
+  const {
+    subscriptions: subscriptionState,
+    settings: { daemonSettings },
+  } = getState();
+  const { subscriptions: reduxSubscriptions } = subscriptionState;
+  const { share_usage_data: isSharingData } = daemonSettings;
 
-  analytics.apiLogSubscribe(subscription);
+  if (!isSharingData && isSharingData !== undefined) {
+    // They aren't sharing their data, subscriptions will be handled by persisted redux state
+    return;
+  }
 
-  dispatch(doCheckSubscription(subscription, true));
+  // most of this logic comes from scenarios where the db isn't synced with redux
+  // this will happen if the user stops sharing data
+  dispatch({ type: ACTIONS.FETCH_SUBSCRIPTIONS_START });
+
+  Lbryio.call('subscription', 'list')
+    .then(dbSubscriptions => {
+      const storedSubscriptions = dbSubscriptions || [];
+
+      // User has no subscriptions in db or redux
+      if (!storedSubscriptions.length && (!reduxSubscriptions || !reduxSubscriptions.length)) {
+        return [];
+      }
+
+      // There is some mismatch between redux state and db state
+      // If something is in the db, but not in redux, add it to redux
+      // If something is in redux, but not in the db, add it to the db
+      if (storedSubscriptions.length !== reduxSubscriptions.length) {
+        const dbSubMap = {};
+        const reduxSubMap = {};
+        const subsNotInDB = [];
+        const subscriptionsToReturn = reduxSubscriptions.slice();
+
+        storedSubscriptions.forEach(sub => {
+          dbSubMap[sub.claim_id] = 1;
+        });
+
+        reduxSubscriptions.forEach(sub => {
+          const { claimId } = parseURI(sub.uri);
+          reduxSubMap[claimId] = 1;
+
+          if (!dbSubMap[claimId]) {
+            subsNotInDB.push({
+              claim_id: claimId,
+              channel_name: sub.channelName,
+            });
+          }
+        });
+
+        storedSubscriptions.forEach(sub => {
+          if (!reduxSubMap[sub.claim_id]) {
+            const uri = `lbry://${sub.channel_name}#${sub.claim_id}`;
+            subscriptionsToReturn.push({ uri, channelName: sub.channel_name });
+          }
+        });
+
+        return Promise.all(subsNotInDB.map(payload => Lbryio.call('subscription', 'new', payload)))
+          .then(() => subscriptionsToReturn)
+          .catch(
+            () =>
+              // let it fail, we will try again when the navigate to the subscriptions page
+              subscriptionsToReturn
+          );
+      }
+
+      // DB is already synced, just return the subscriptions in redux
+      return reduxSubscriptions;
+    })
+    .then(subscriptions => {
+      dispatch({
+        type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS,
+        data: subscriptions,
+      });
+    })
+    .catch(() => {
+      dispatch({
+        type: ACTIONS.FETCH_SUBSCRIPTIONS_FAIL,
+      });
+    });
 };
 
-export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: Dispatch) => {
+export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (
+  dispatch: Dispatch
+) =>
   dispatch({
-    type: ACTIONS.CHANNEL_UNSUBSCRIBE,
-    data: subscription,
+    type: ACTIONS.SET_SUBSCRIPTION_LATEST,
+    data: {
+      subscription,
+      uri,
+    },
   });
 
-  analytics.apiLogUnsubscribe(subscription);
-};
-
-export const doCheckSubscriptions = () => (
-  dispatch: Dispatch,
-  getState: () => SubscriptionState
-) => {
-  const checkSubscriptionsTimer = setInterval(
-    () =>
-      selectSubscriptions(getState()).map((subscription: Subscription) =>
-        dispatch(doCheckSubscription(subscription, true))
-      ),
-    CHECK_SUBSCRIPTIONS_INTERVAL
-  );
+export const setSubscriptionNotification = (
+  subscription: Subscription,
+  uri: string,
+  notificationType: string
+) => (dispatch: Dispatch) =>
   dispatch({
-    type: ACTIONS.CHECK_SUBSCRIPTIONS_SUBSCRIBE,
-    data: { checkSubscriptionsTimer },
+    type: ACTIONS.SET_SUBSCRIPTION_NOTIFICATION,
+    data: {
+      subscription,
+      uri,
+      type: notificationType,
+    },
   });
-};
 
 export const doCheckSubscription = (subscription: Subscription, notify?: boolean) => (
   dispatch: Dispatch
@@ -114,31 +185,6 @@ export const doCheckSubscription = (subscription: Subscription, notify?: boolean
   });
 };
 
-export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (
-  dispatch: Dispatch
-) =>
-  dispatch({
-    type: ACTIONS.SET_SUBSCRIPTION_LATEST,
-    data: {
-      subscription,
-      uri,
-    },
-  });
-
-export const setSubscriptionNotification = (
-  subscription: Subscription,
-  uri: string,
-  notificationType: string
-) => (dispatch: Dispatch) =>
-  dispatch({
-    type: ACTIONS.SET_SUBSCRIPTION_NOTIFICATION,
-    data: {
-      subscription,
-      uri,
-      type: notificationType,
-    },
-  });
-
 export const setSubscriptionNotifications = (notifications: SubscriptionNotifications) => (
   dispatch: Dispatch
 ) =>
@@ -149,5 +195,68 @@ export const setSubscriptionNotifications = (notifications: SubscriptionNotifica
     },
   });
 
-export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) =>
-  dispatch({ type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS });
+export const doChannelSubscribe = (subscription: Subscription) => (
+  dispatch: Dispatch,
+  getState: () => any
+) => {
+  const {
+    settings: { daemonSettings },
+  } = getState();
+  const { share_usage_data: isSharingData } = daemonSettings;
+
+  dispatch({
+    type: ACTIONS.CHANNEL_SUBSCRIBE,
+    data: subscription,
+  });
+
+  // if the user isn't sharing data, keep the subscriptions entirely in the app
+  if (isSharingData) {
+    const { claimId } = parseURI(subscription.uri);
+    // They are sharing data, we can store their subscriptions in our internal database
+    Lbryio.call('subscription', 'new', {
+      channel_name: subscription.channelName,
+      claim_id: claimId,
+    });
+  }
+
+  dispatch(doCheckSubscription(subscription, true));
+};
+
+export const doChannelUnsubscribe = (subscription: Subscription) => (
+  dispatch: Dispatch,
+  getState: () => any
+) => {
+  const {
+    settings: { daemonSettings },
+  } = getState();
+  const { share_usage_data: isSharingData } = daemonSettings;
+
+  dispatch({
+    type: ACTIONS.CHANNEL_UNSUBSCRIBE,
+    data: subscription,
+  });
+
+  if (isSharingData) {
+    const { claimId } = parseURI(subscription.uri);
+    Lbryio.call('subscription', 'delete', {
+      claim_id: claimId,
+    });
+  }
+};
+
+export const doCheckSubscriptions = () => (
+  dispatch: Dispatch,
+  getState: () => SubscriptionState
+) => {
+  const checkSubscriptionsTimer = setInterval(
+    () =>
+      selectSubscriptions(getState()).map((subscription: Subscription) =>
+        dispatch(doCheckSubscription(subscription, true))
+      ),
+    CHECK_SUBSCRIPTIONS_INTERVAL
+  );
+  dispatch({
+    type: ACTIONS.CHECK_SUBSCRIPTIONS_SUBSCRIBE,
+    data: { checkSubscriptionsTimer },
+  });
+};
diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js
index 7a54e2d46..348528007 100644
--- a/src/renderer/redux/reducers/subscriptions.js
+++ b/src/renderer/redux/reducers/subscriptions.js
@@ -2,12 +2,7 @@
 import * as ACTIONS from 'constants/action_types';
 import * as NOTIFICATION_TYPES from 'constants/notification_types';
 import { handleActions } from 'util/redux-utils';
-
-export type Subscription = {
-  channelName: string,
-  uri: string,
-  latest: ?string,
-};
+import type { Subscription } from 'types/subscription';
 
 export type NotificationType =
   | NOTIFICATION_TYPES.DOWNLOADING
@@ -24,8 +19,8 @@ export type SubscriptionNotifications = {
 // Subscription redux types
 export type SubscriptionState = {
   subscriptions: Array<Subscription>,
-  hasFetchedSubscriptions: boolean,
   notifications: SubscriptionNotifications,
+  loading: boolean,
 };
 
 // Subscription action types
@@ -39,10 +34,6 @@ type doChannelUnsubscribe = {
   data: Subscription,
 };
 
-type HasFetchedSubscriptions = {
-  type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS,
-};
-
 type setSubscriptionLatest = {
   type: ACTIONS.SET_SUBSCRIPTION_LATEST,
   data: {
@@ -75,10 +66,14 @@ type CheckSubscriptionCompleted = {
   type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED,
 };
 
+type fetchedSubscriptionsSucess = {
+  type: ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS,
+  data: Array<Subscription>,
+};
+
 export type Action =
   | doChannelSubscribe
   | doChannelUnsubscribe
-  | HasFetchedSubscriptions
   | setSubscriptionLatest
   | setSubscriptionNotification
   | CheckSubscriptionStarted
@@ -88,8 +83,8 @@ export type Dispatch = (action: Action) => any;
 
 const defaultState = {
   subscriptions: [],
-  hasFetchedSubscriptions: false,
   notifications: {},
+  loading: false,
 };
 
 export default handleActions(
@@ -122,10 +117,6 @@ export default handleActions(
         subscriptions: newSubscriptions,
       };
     },
-    [ACTIONS.HAS_FETCHED_SUBSCRIPTIONS]: (state: SubscriptionState): SubscriptionState => ({
-      ...state,
-      hasFetchedSubscriptions: true,
-    }),
     [ACTIONS.SET_SUBSCRIPTION_LATEST]: (
       state: SubscriptionState,
       action: setSubscriptionLatest
@@ -155,6 +146,22 @@ export default handleActions(
       ...state,
       notifications: action.data.notifications,
     }),
+    [ACTIONS.FETCH_SUBSCRIPTIONS_START]: (state: SubscriptionState): SubscriptionState => ({
+      ...state,
+      loading: true,
+    }),
+    [ACTIONS.FETCH_SUBSCRIPTIONS_FAIL]: (state: SubscriptionState): SubscriptionState => ({
+      ...state,
+      loading: false,
+    }),
+    [ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS]: (
+      state: SubscriptionState,
+      action: fetchedSubscriptionsSucess
+    ): SubscriptionState => ({
+      ...state,
+      loading: false,
+      subscriptions: action.data,
+    }),
   },
   defaultState
 );
diff --git a/src/renderer/redux/selectors/subscriptions.js b/src/renderer/redux/selectors/subscriptions.js
index 8f5f9d6ba..1e9ca71cd 100644
--- a/src/renderer/redux/selectors/subscriptions.js
+++ b/src/renderer/redux/selectors/subscriptions.js
@@ -1,15 +1,21 @@
 import { createSelector } from 'reselect';
-import { selectAllClaimsByChannel, selectClaimsById } from 'lbry-redux';
+import {
+  selectAllClaimsByChannel,
+  selectClaimsById,
+  selectAllFetchingChannelClaims,
+} from 'lbry-redux';
 
 // get the entire subscriptions state
 const selectState = state => state.subscriptions || {};
 
+export const selectIsFetchingSubscriptions = createSelector(selectState, state => state.loading);
+
 export const selectNotifications = createSelector(selectState, state => state.notifications);
 
 // list of saved channel names and uris
 export const selectSubscriptions = createSelector(selectState, state => state.subscriptions);
 
-export const selectSubscriptionsFromClaims = createSelector(
+export const selectSubscriptionClaims = createSelector(
   selectAllClaimsByChannel,
   selectClaimsById,
   selectSubscriptions,
@@ -37,9 +43,6 @@ export const selectSubscriptionsFromClaims = createSelector(
         });
       }
 
-      // all we really need is a uri for each claim
-      channelClaims = channelClaims.map(claim => `${claim.name}#${claim.claim_id}`);
-
       fetchedSubscriptions.push({
         claims: channelClaims,
         channelName: subscription.channelName,
@@ -50,3 +53,19 @@ export const selectSubscriptionsFromClaims = createSelector(
     return fetchedSubscriptions;
   }
 );
+
+export const selectSubscriptionsBeingFetched = createSelector(
+  selectSubscriptions,
+  selectAllFetchingChannelClaims,
+  (subscriptions, fetchingChannelClaims) => {
+    const fetchingSubscriptionMap = {};
+    subscriptions.forEach(sub => {
+      const isFetching = fetchingChannelClaims && fetchingChannelClaims[sub.uri];
+      if (isFetching) {
+        fetchingSubscriptionMap[sub.uri] = 1;
+      }
+    });
+
+    return fetchingSubscriptionMap;
+  }
+);
diff --git a/src/renderer/scss/_gui.scss b/src/renderer/scss/_gui.scss
index 9904a94f9..8fc1aeeb9 100644
--- a/src/renderer/scss/_gui.scss
+++ b/src/renderer/scss/_gui.scss
@@ -221,6 +221,9 @@ p {
   margin-top: 200px;
   text-align: center;
   font-family: 'metropolis-medium';
+  display: flex;
+  flex-direction: column;
+  align-items: center;
 }
 
 .columns {
diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss
index e190cd177..8bd63a98d 100644
--- a/src/renderer/scss/component/_card.scss
+++ b/src/renderer/scss/component/_card.scss
@@ -299,23 +299,10 @@
     display: inline-block;
     vertical-align: top;
     margin-bottom: 60px;
+    width: calc((100% / 4) - (60px / 4));
 
-    @media only screen and (max-width: $medium-breakpoint) {
-      width: calc((100% / 3) - (40px / 3));
-
-      &:not(:nth-child(3n + 1)) {
-        margin-left: 20px;
-      }
-    }
-  }
-
-  @media only screen and (min-width: $medium-breakpoint) {
-    .card {
-      width: calc((100% / 4) - (60px / 4));
-
-      &:not(:nth-child(4n + 1)) {
-        margin-left: 20px;
-      }
+    &:not(:nth-child(4n + 1)) {
+      margin-left: 20px;
     }
   }
 }
@@ -341,8 +328,8 @@
     display: inline-block;
     vertical-align: top;
     overflow: visible;
-    // 35 px to handle to padding between cards
-    width: calc((100% / 3) - 35px);
+    // 31 px to handle to padding between cards
+    width: calc((100% / 4) - 31px);
   }
 
   .card:not(:first-of-type) {
@@ -352,13 +339,6 @@
   .card:last-of-type {
     margin-right: 20px;
   }
-
-  @media only screen and (min-width: $medium-breakpoint) {
-    .card {
-      // 31 px to handle to padding between cards
-      width: calc((100% / 4) - 31px);
-    }
-  }
 }
 
 .card__success-msg {
diff --git a/src/renderer/scss/component/_spinner.scss b/src/renderer/scss/component/_spinner.scss
index 09433cbb1..bdeda87ab 100644
--- a/src/renderer/scss/component/_spinner.scss
+++ b/src/renderer/scss/component/_spinner.scss
@@ -10,7 +10,6 @@
     height: 100%;
     width: 6px;
     margin: 0 2px;
-    background-color: var(--color-white);
     animation: sk-stretchdelay 1.2s infinite ease-in-out;
 
     &.rect2 {
@@ -31,6 +30,12 @@
   }
 }
 
+.spinner--light {
+  .rect {
+    background-color: var(--color-white);
+  }
+}
+
 .spinner--dark {
   .rect {
     background-color: var(--color-black);
diff --git a/src/renderer/store.js b/src/renderer/store.js
index 7ab581a7b..690387ffe 100644
--- a/src/renderer/store.js
+++ b/src/renderer/store.js
@@ -102,6 +102,7 @@ const store = createStore(
 const compressor = createCompressor();
 const saveClaimsFilter = createFilter('claims', ['byId', 'claimsByUri']);
 const subscriptionsFilter = createFilter('subscriptions', ['subscriptions']);
+
 // We only need to persist the receiveAddress for the wallet
 const walletFilter = createFilter('wallet', ['receiveAddress']);
 
diff --git a/src/renderer/types/claim.js b/src/renderer/types/claim.js
new file mode 100644
index 000000000..2f858a9a6
--- /dev/null
+++ b/src/renderer/types/claim.js
@@ -0,0 +1,30 @@
+// @flow
+
+// Actual claim type has more values than this
+// Add them as they are used
+export type Claim = {
+  address: string,
+  amount: number,
+  claim_id: string,
+  claim_sequence: number,
+  decoded_claim: boolean,
+  depth: number,
+  effective_amount: number,
+  has_signature: boolean,
+  height: number,
+  has_signature: boolean,
+  hex: string,
+  name: string,
+  nout: number,
+  permanent_url: string,
+  channel_name: ?string,
+  txid: string,
+  nout: number,
+  signature_is_valid: boolean,
+  valid_at_height: number,
+  value: {
+    publisherSignature: ?{
+      certificateId: ?string,
+    },
+  },
+};
diff --git a/src/renderer/types/subscription.js b/src/renderer/types/subscription.js
new file mode 100644
index 000000000..dc7a4c744
--- /dev/null
+++ b/src/renderer/types/subscription.js
@@ -0,0 +1,7 @@
+// @flow
+
+export type Subscription = {
+  channelName: string, // @CryptoCandor,
+  uri: string, // lbry://@CryptoCandor#9152f3b054f692076a6882d1b58a30e8781cc8e6
+  latest: string, // substratum#b0ab143243020e7831fd070d9f871e1fda948620
+};
diff --git a/src/renderer/util/dom.js b/src/renderer/util/dom.js
new file mode 100644
index 000000000..3f93a94a8
--- /dev/null
+++ b/src/renderer/util/dom.js
@@ -0,0 +1,12 @@
+// @flow
+import * as React from 'react';
+
+// is a child component being rendered?
+export const isShowingChildren = (children: React.Node): boolean => {
+  if (Array.isArray(children)) {
+    const firstChildIndex = children.findIndex(child => child);
+    return firstChildIndex > -1;
+  }
+
+  return !!children;
+};