Browse Source

removing unnecessary src1 folder

rohit.gowda 4 years ago
parent
commit
325a50ac5b
97 changed files with 0 additions and 25834 deletions
  1. 0 94
      src1/app/app.component.ts
  2. 0 34
      src1/app/app.html
  3. 0 104
      src1/app/app.module.ts
  4. 0 60
      src1/app/app.scss
  5. 0 5
      src1/app/main.ts
  6. BIN
      src1/assets/icon/favicon.ico
  7. BIN
      src1/assets/imgs/background-login-sm.png
  8. BIN
      src1/assets/imgs/background-login.png
  9. BIN
      src1/assets/imgs/logo.png
  10. 0 21544
      src1/assets/scripts/openpgp.js
  11. 0 145
      src1/assets/scripts/openpgp.worker.js
  12. 0 36
      src1/components/components.module.ts
  13. 0 13
      src1/components/feed/feed.html
  14. 0 0
      src1/components/feed/feed.scss
  15. 0 36
      src1/components/feed/feed.ts
  16. 0 2
      src1/components/hashtag/hashtag.html
  17. 0 5
      src1/components/hashtag/hashtag.scss
  18. 0 18
      src1/components/hashtag/hashtag.ts
  19. 0 2
      src1/components/mention/mention.html
  20. 0 5
      src1/components/mention/mention.scss
  21. 0 20
      src1/components/mention/mention.ts
  22. 0 28
      src1/components/profile-header/profile-header.html
  23. 0 25
      src1/components/profile-header/profile-header.scss
  24. 0 45
      src1/components/profile-header/profile-header.ts
  25. 0 13
      src1/components/quoted-status/quoted-status.html
  26. 0 43
      src1/components/quoted-status/quoted-status.scss
  27. 0 24
      src1/components/quoted-status/quoted-status.ts
  28. 0 24
      src1/components/tweet-actions/tweet-actions.html
  29. 0 33
      src1/components/tweet-actions/tweet-actions.scss
  30. 0 93
      src1/components/tweet-actions/tweet-actions.ts
  31. 0 15
      src1/components/tweet-body/tweet-body.html
  32. 0 22
      src1/components/tweet-body/tweet-body.scss
  33. 0 204
      src1/components/tweet-body/tweet-body.ts
  34. 0 14
      src1/components/tweet-header/tweet-header.html
  35. 0 39
      src1/components/tweet-header/tweet-header.scss
  36. 0 107
      src1/components/tweet-header/tweet-header.ts
  37. 0 7
      src1/components/tweet/tweet.html
  38. 0 23
      src1/components/tweet/tweet.scss
  39. 0 34
      src1/components/tweet/tweet.ts
  40. 0 51
      src1/index.html
  41. 0 13
      src1/manifest.json
  42. 0 11
      src1/pages/about/about.html
  43. 0 13
      src1/pages/about/about.module.ts
  44. 0 3
      src1/pages/about/about.scss
  45. 0 11
      src1/pages/about/about.ts
  46. 0 18
      src1/pages/home/home.html
  47. 0 9
      src1/pages/home/home.module.ts
  48. 0 0
      src1/pages/home/home.scss
  49. 0 91
      src1/pages/home/home.ts
  50. 0 13
      src1/pages/login/login.html
  51. 0 9
      src1/pages/login/login.module.ts
  52. 0 33
      src1/pages/login/login.scss
  53. 0 53
      src1/pages/login/login.ts
  54. 0 15
      src1/pages/profile/profile.html
  55. 0 9
      src1/pages/profile/profile.module.ts
  56. 0 3
      src1/pages/profile/profile.scss
  57. 0 128
      src1/pages/profile/profile.ts
  58. 0 4
      src1/pages/search-results-tweets-popular/search-results-tweets-popular.html
  59. 0 13
      src1/pages/search-results-tweets-popular/search-results-tweets-popular.module.ts
  60. 0 5
      src1/pages/search-results-tweets-popular/search-results-tweets-popular.scss
  61. 0 80
      src1/pages/search-results-tweets-popular/search-results-tweets-popular.ts
  62. 0 4
      src1/pages/search-results-tweets-recent/search-results-tweets-recent.html
  63. 0 13
      src1/pages/search-results-tweets-recent/search-results-tweets-recent.module.ts
  64. 0 5
      src1/pages/search-results-tweets-recent/search-results-tweets-recent.scss
  65. 0 78
      src1/pages/search-results-tweets-recent/search-results-tweets-recent.ts
  66. 0 6
      src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.html
  67. 0 13
      src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.module.ts
  68. 0 2
      src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.scss
  69. 0 21
      src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.ts
  70. 0 24
      src1/pages/search-results-users/search-results-users.html
  71. 0 13
      src1/pages/search-results-users/search-results-users.module.ts
  72. 0 6
      src1/pages/search-results-users/search-results-users.scss
  73. 0 67
      src1/pages/search-results-users/search-results-users.ts
  74. 0 13
      src1/pages/search/search.html
  75. 0 0
      src1/pages/search/search.scss
  76. 0 26
      src1/pages/search/search.ts
  77. 0 40
      src1/pages/settings/settings.html
  78. 0 0
      src1/pages/settings/settings.scss
  79. 0 151
      src1/pages/settings/settings.ts
  80. 0 45
      src1/pages/write-tweet/write-tweet.html
  81. 0 9
      src1/pages/write-tweet/write-tweet.module.ts
  82. 0 53
      src1/pages/write-tweet/write-tweet.scss
  83. 0 379
      src1/pages/write-tweet/write-tweet.ts
  84. 0 18
      src1/pipes/diff-for-humans/diff-for-humans.ts
  85. 0 19
      src1/pipes/friendly-number/friendly-number.ts
  86. 0 15
      src1/pipes/high-resolution/high-resolution.ts
  87. 0 24
      src1/pipes/pipes.module.ts
  88. 0 20
      src1/pipes/replace-hashtags/replace-hashtags.ts
  89. 0 24
      src1/pipes/replace-urls/replace-urls.ts
  90. 0 72
      src1/providers/auth/auth.ts
  91. 0 347
      src1/providers/crypto/crypto.ts
  92. 0 229
      src1/providers/feed/feed.ts
  93. 0 130
      src1/providers/p2p-database-gun/p2p-database-gun.ts
  94. 0 64
      src1/providers/p2p-storage-ipfs/p2p-storage-ipfs.ts
  95. 0 284
      src1/providers/twitter-api/twitter-api.ts
  96. 0 31
      src1/service-worker.js
  97. 0 88
      src1/theme/variables.scss

+ 0 - 94
src1/app/app.component.ts

@@ -1,94 +0,0 @@
-import { Component, ViewChild } from "@angular/core";
-import { Nav, Platform, Events } from "ionic-angular";
-import { StatusBar } from "@ionic-native/status-bar";
-import { SplashScreen } from "@ionic-native/splash-screen";
-import { Storage } from "@ionic/storage";
-
-import { AuthProvider } from "../providers/auth/auth";
-
-import { HomePage } from "../pages/home/home";
-import { SearchPage } from "../pages/search/search";
-import { SettingsPage } from "../pages/settings/settings";
-import { LoginPage } from "../pages/login/login";
-import { ProfilePage } from "../pages/profile/profile";
-import { TwitterApiProvider } from "../providers/twitter-api/twitter-api";
-
-@Component({
-  templateUrl: "app.html"
-})
-export class MyApp {
-  @ViewChild(Nav)
-  nav: Nav;
-
-  rootPage: any;
-  pages: Array<{ title: string; icon: string; component: any }>;
-  user: any;
-
-  constructor(
-    platform: Platform,
-    statusBar: StatusBar,
-    splashScreen: SplashScreen,
-    private authProvider: AuthProvider,
-    private twitter: TwitterApiProvider,
-    private storage: Storage,
-    private events: Events
-  ) {
-    platform.ready().then(() => {
-      // Okay, so the platform is ready and our plugins are available.
-      // Here you can do any higher level native things you might need.
-
-      statusBar.styleDefault();
-      splashScreen.hide();
-      this.initApp();
-
-      this.events.subscribe("user:login", () => this.setUser());
-    });
-
-    this.pages = [
-      { title: "Home", icon: "home", component: HomePage },
-      { title: "Search", icon: "search", component: SearchPage },
-      { title: "Settings", icon: "settings", component: SettingsPage }
-    ];
-  }
-
-  async initApp() {
-    const isLoggedIn = await this.authProvider.isLoggedIn();
-
-    if (isLoggedIn) {
-      this.rootPage = HomePage;
-      await this.setUser();
-    } else {
-      this.rootPage = LoginPage;
-    }
-  }
-
-  async setUser() {
-    const userId = await this.storage.get("userId");
-    this.user = await this.twitter.fetchUser(userId);
-  }
-
-  showProfile(userId) {
-    this.nav.push(ProfilePage, { userId });
-  }
-
-  openPage(page) {
-    if (page.component === HomePage) {
-      this.nav.setRoot(HomePage);
-    } else {
-      this.nav.push(page.component);
-    }
-  }
-
-  logout() {
-    this.authProvider.logout();
-    this.nav.setRoot(LoginPage);
-  }
-
-  get banner() {
-    if (this.user.profile_banner_url) {
-      return this.user.profile_banner_url;
-    } else {
-      return this.user.profile_background_image_url_https;
-    }
-  }
-}

+ 0 - 34
src1/app/app.html

@@ -1,34 +0,0 @@
-<ion-menu id="sideNav" [content]="content">
-  <ion-header>
-    <ion-toolbar>
-      <ion-title>Menu</ion-title>
-    </ion-toolbar>
-  </ion-header>
-
-  <ion-content>
-    <div class="user-info" *ngIf="user" (click)="showProfile(user.id)" menuClose>
-      <div class="user-banner" [style.background]="'url('+ banner +')'">
-        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px"
-          viewBox="0 0 300 100" xml:space="preserve" width="100%" class="svg-triangle">
-          <polygon points="0,75  0,100 300,100 300,99" fill="#FFFFFF" />
-        </svg>
-        <img src="{{ user.profile_image_url_https | highResolution }}" alt="User" class="user-avatar">
-      </div>
-      <div class="user-info">
-        {{user.name}}<br><span class="handle">@{{user.screen_name}}</span>
-      </div>
-    </div>
-    <ion-list>
-      <button menuClose ion-item no-padding icon-start *ngFor="let page of pages" (click)="openPage(page)">
-        <ion-icon name="{{page.icon}}"></ion-icon>{{page.title}}
-      </button>
-      <button menuClose ion-item no-padding icon-start (click)="logout()">
-        <ion-icon name="log-out"></ion-icon>Logout
-      </button>
-    </ion-list>
-  </ion-content>
-
-</ion-menu>
-
-<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
-<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>

+ 0 - 104
src1/app/app.module.ts

@@ -1,104 +0,0 @@
-import { BrowserModule } from "@angular/platform-browser";
-import { ErrorHandler, NgModule } from "@angular/core";
-import { IonicApp, IonicErrorHandler, IonicModule } from "ionic-angular";
-import { SplashScreen } from "@ionic-native/splash-screen";
-import { StatusBar } from "@ionic-native/status-bar";
-import { HttpClient, HttpClientModule } from "@angular/common/http";
-import { IonicStorageModule } from "@ionic/storage";
-import { SocialSharing } from "@ionic-native/social-sharing";
-import { PhotoViewer } from "@ionic-native/photo-viewer";
-import { Vibration } from "@ionic-native/vibration";
-
-import { AuthProvider } from "../providers/auth/auth";
-
-import { MyApp } from "./app.component";
-import { HomePage } from "../pages/home/home";
-import { SearchPage } from "../pages/search/search";
-import { SettingsPage } from "../pages/settings/settings";
-import { LoginPage } from "../pages/login/login";
-import { TwitterApiProvider } from "../providers/twitter-api/twitter-api";
-import { FeedComponent } from "../components/feed/feed";
-import { TweetComponent } from "../components/tweet/tweet";
-import { TweetHeaderComponent } from "../components/tweet-header/tweet-header";
-import { TweetBodyComponent } from "../components/tweet-body/tweet-body";
-import { TweetActionsComponent } from "../components/tweet-actions/tweet-actions";
-import { ProfilePage } from "../pages/profile/profile";
-import { ProfileHeaderComponent } from "../components/profile-header/profile-header";
-import { PipesModule } from "../pipes/pipes.module";
-import { WriteTweetPage } from "../pages/write-tweet/write-tweet";
-import { QuotedStatusComponent } from "../components/quoted-status/quoted-status";
-import { P2pStorageIpfsProvider } from "../providers/p2p-storage-ipfs/p2p-storage-ipfs";
-import { P2pDatabaseGunProvider } from "../providers/p2p-database-gun/p2p-database-gun";
-import { FeedProvider } from "../providers/feed/feed";
-import { MentionComponent } from "../components/mention/mention";
-import { HashtagComponent } from "../components/hashtag/hashtag";
-import { SearchResultsUsersPage } from "../pages/search-results-users/search-results-users";
-import { SearchResultsTweetsPopularPage } from "../pages/search-results-tweets-popular/search-results-tweets-popular";
-import { SearchResultsTweetsRecentPage } from "../pages/search-results-tweets-recent/search-results-tweets-recent";
-import { SearchResultsTweetsTabsPage } from "../pages/search-results-tweets-tabs/search-results-tweets-tabs";
-import { AboutPage } from "../pages/about/about";
-import { CryptoProvider } from "../providers/crypto/crypto";
-
-@NgModule({
-  declarations: [
-    MyApp,
-    HomePage,
-    SearchPage,
-    SettingsPage,
-    LoginPage,
-    ProfilePage,
-    WriteTweetPage,
-    SearchResultsTweetsTabsPage,
-    SearchResultsTweetsRecentPage,
-    SearchResultsTweetsPopularPage,
-    SearchResultsUsersPage,
-    AboutPage,
-    FeedComponent,
-    TweetComponent,
-    TweetHeaderComponent,
-    TweetBodyComponent,
-    TweetActionsComponent,
-    ProfileHeaderComponent,
-    QuotedStatusComponent,
-    MentionComponent,
-    HashtagComponent
-  ],
-  imports: [
-    BrowserModule,
-    HttpClientModule,
-    IonicModule.forRoot(MyApp),
-    IonicStorageModule.forRoot(),
-    PipesModule
-  ],
-  bootstrap: [IonicApp],
-  entryComponents: [
-    MyApp,
-    HomePage,
-    SearchPage,
-    SettingsPage,
-    LoginPage,
-    ProfilePage,
-    WriteTweetPage,
-    SearchResultsTweetsTabsPage,
-    SearchResultsTweetsRecentPage,
-    SearchResultsTweetsPopularPage,
-    SearchResultsUsersPage,
-    AboutPage
-  ],
-  providers: [
-    StatusBar,
-    SplashScreen,
-    HttpClient,
-    SocialSharing,
-    PhotoViewer,
-    { provide: ErrorHandler, useClass: IonicErrorHandler },
-    AuthProvider,
-    TwitterApiProvider,
-    P2pStorageIpfsProvider,
-    P2pDatabaseGunProvider,
-    FeedProvider,
-    CryptoProvider,
-    Vibration
-  ]
-})
-export class AppModule {}

+ 0 - 60
src1/app/app.scss

@@ -1,60 +0,0 @@
-// http://ionicframework.com/docs/theming/
-// App Global Sass
-// --------------------------------------------------
-// Put style rules here that you want to apply globally. These
-// styles are for the entire app and not just one component.
-// Additionally, this file can be also used as an entry point
-// to import other Sass files to be included in the output CSS.
-//
-// Shared Sass variables, which can be used to adjust Ionic's
-// default Sass variables, belong in "theme/variables.scss".
-//
-// To declare rules for a specific mode, create a child rule
-// for the .md, .ios, or .wp mode classes. The mode class is
-// automatically applied to the <body> element in the app.
-.icon.icon-verified {
-  color: #1da1f2;
-}
-
-#sideNav {
-  .user-info {
-    .user-banner {
-      position: relative;
-      height: 140px;
-      margin-bottom: 20px;
-      .svg-triangle {
-        position: absolute;
-        bottom: 0;
-      }
-      .user-avatar {
-        position: absolute;
-        bottom: -10px;
-        left: 15px;
-        border-radius: 50%;
-        width: 90px;
-      }
-    }
-    .user-info {
-      padding: 0 15px;
-      font-size: 15px;
-      font-weight: 500;
-      margin-bottom: 10px;
-      .handle {
-        color: #ababab;
-        font-weight: 300;
-        font-size: 11px;
-      }
-    }
-  }
-  .label-md {
-    margin-left: 8px;
-    display: flex;
-    align-items: center;
-  }
-  .item-inner {
-    padding-left: 8px;
-  }
-  .ion-icon {
-    line-height: 1;
-  }
-}

+ 0 - 5
src1/app/main.ts

@@ -1,5 +0,0 @@
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-
-import { AppModule } from './app.module';
-
-platformBrowserDynamic().bootstrapModule(AppModule);

BIN
src1/assets/icon/favicon.ico


BIN
src1/assets/imgs/background-login-sm.png


BIN
src1/assets/imgs/background-login.png


BIN
src1/assets/imgs/logo.png


File diff suppressed because it is too large
+ 0 - 21544
src1/assets/scripts/openpgp.js


+ 0 - 145
src1/assets/scripts/openpgp.worker.js

@@ -1,145 +0,0 @@
-(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
-// GPG4Browsers - An OpenPGP implementation in javascript
-// Copyright (C) 2011 Recurity Labs GmbH
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 3.0 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-/* eslint-disable no-restricted-globals */
-/* eslint-disable no-var */
-/* eslint-disable vars-on-top */
-
-/**
- * @fileoverview Provides functions for communicating with workers
- * @see module:openpgp.initWorker
- * @see module:openpgp.getWorker
- * @see module:openpgp.destroyWorker
- * @see module:worker/async_proxy
- * @module worker/worker
- */
-
-self.window = self; // to make UMD bundles work
-
-importScripts('openpgp.js');
-var openpgp = window.openpgp;
-
-var randomQueue = [];
-var MAX_SIZE_RANDOM_BUFFER = 60000;
-
-/**
- * Handle random buffer exhaustion by requesting more random bytes from the main window
- * @returns {Promise<Object>}  Empty promise whose resolution indicates that the buffer has been refilled
- */
-function randomCallback() {
-
-  if (!randomQueue.length) {
-    self.postMessage({ event: 'request-seed', amount: MAX_SIZE_RANDOM_BUFFER });
-  }
-
-  return new Promise(function(resolve) {
-    randomQueue.push(resolve);
-  });
-}
-
-openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER, randomCallback);
-
-/**
- * Handle messages from the main window.
- * @param  {Object} event   Contains event type and data
- */
-self.onmessage = function(event) {
-  var msg = event.data || {};
-
-  switch (msg.event) {
-    case 'configure':
-      configure(msg.config);
-      break;
-
-    case 'seed-random':
-      seedRandom(msg.buf);
-
-      var queueCopy = randomQueue;
-      randomQueue = [];
-      for (var i = 0; i < queueCopy.length; i++) {
-        queueCopy[i]();
-      }
-
-      break;
-
-    default:
-      delegate(msg.id, msg.event, msg.options || {});
-  }
-};
-
-/**
- * Set config from main context to worker context.
- * @param  {Object} config   The openpgp configuration
- */
-function configure(config) {
-  Object.keys(config).forEach(function(key) {
-    openpgp.config[key] = config[key];
-  });
-}
-
-/**
- * Seed the library with entropy gathered window.crypto.getRandomValues
- * as this api is only avalible in the main window.
- * @param  {ArrayBuffer} buffer   Some random bytes
- */
-function seedRandom(buffer) {
-  if (!(buffer instanceof Uint8Array)) {
-    buffer = new Uint8Array(buffer);
-  }
-  openpgp.crypto.random.randomBuffer.set(buffer);
-}
-
-/**
- * Generic proxy function that handles all commands from the public api.
- * @param  {String} method    The public api function to be delegated to the worker thread
- * @param  {Object} options   The api function's options
- */
-function delegate(id, method, options) {
-  if (typeof openpgp[method] !== 'function') {
-    response({ id:id, event:'method-return', err:'Unknown Worker Event' });
-    return;
-  }
-  // construct ReadableStreams from MessagePorts
-  openpgp.util.restoreStreams(options);
-  // parse cloned packets
-  options = openpgp.packet.clone.parseClonedPackets(options, method);
-  openpgp[method](options).then(function(data) {
-    // clone packets (for web worker structured cloning algorithm)
-    response({ id:id, event:'method-return', data:openpgp.packet.clone.clonePackets(data) });
-  }).catch(function(e) {
-    openpgp.util.print_debug_error(e);
-    response({
-      id:id, event:'method-return', err:e.message, stack:e.stack
-    });
-  });
-}
-
-/**
- * Respond to the main window.
- * @param  {Object} event  Contains event type and data
- */
-function response(event) {
-  self.postMessage(event, openpgp.util.getTransferables(event.data, true));
-}
-
-/**
- * Let the main window know the worker has loaded.
- */
-postMessage({ event: 'loaded' });
-
-},{}]},{},[1]);

+ 0 - 36
src1/components/components.module.ts

@@ -1,36 +0,0 @@
-import { NgModule } from "@angular/core";
-import { FeedComponent } from "./feed/feed";
-import { TweetComponent } from "./tweet/tweet";
-import { TweetHeaderComponent } from "./tweet-header/tweet-header";
-import { TweetBodyComponent } from "./tweet-body/tweet-body";
-import { TweetActionsComponent } from "./tweet-actions/tweet-actions";
-import { ProfileHeaderComponent } from "./profile-header/profile-header";
-import { QuotedStatusComponent } from "./quoted-status/quoted-status";
-import { HashtagComponent } from "./hashtag/hashtag";
-import { MentionComponent } from "./mention/mention";
-@NgModule({
-  declarations: [
-    FeedComponent,
-    TweetComponent,
-    TweetHeaderComponent,
-    TweetBodyComponent,
-    TweetActionsComponent,
-    ProfileHeaderComponent,
-    QuotedStatusComponent,
-    HashtagComponent,
-    MentionComponent
-  ],
-  imports: [],
-  exports: [
-    FeedComponent,
-    TweetComponent,
-    TweetHeaderComponent,
-    TweetBodyComponent,
-    TweetActionsComponent,
-    ProfileHeaderComponent,
-    QuotedStatusComponent,
-    HashtagComponent,
-    MentionComponent
-  ]
-})
-export class ComponentsModule {}

+ 0 - 13
src1/components/feed/feed.html

@@ -1,13 +0,0 @@
-<ion-content>
-  <ion-refresher (ionRefresh)="doRefresh($event)" enabled="{{enableRefresh}}">
-    <ion-refresher-content pullingText="Pull to refresh" refreshingText="Refreshing..."></ion-refresher-content>
-  </ion-refresher>
-
-  <ion-list>
-    <tweet *ngFor="let tweet of data" [data]="tweet"></tweet>
-  </ion-list>
-
-  <ion-infinite-scroll (ionInfinite)="doInfinite($event)" enabled="{{enableInfiniteScroll}}">
-    <ion-infinite-scroll-content loadingText="Loading more tweets..."></ion-infinite-scroll-content>
-  </ion-infinite-scroll>
-</ion-content>

+ 0 - 0
src1/components/feed/feed.scss


+ 0 - 36
src1/components/feed/feed.ts

@@ -1,36 +0,0 @@
-import {
-  Component,
-  Input,
-  Output,
-  ChangeDetectionStrategy,
-  EventEmitter
-} from "@angular/core";
-import { Refresher } from "ionic-angular";
-
-@Component({
-  selector: "feed",
-  templateUrl: "feed.html",
-  changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class FeedComponent {
-  @Input()
-  data: any[];
-  @Input()
-  enableRefresh: boolean = true;
-  @Input()
-  enableInfiniteScroll: boolean = true;
-  @Output()
-  onRefresh: EventEmitter<any> = new EventEmitter<any>();
-  @Output()
-  onLoadMore: EventEmitter<any> = new EventEmitter<any>();
-
-  constructor() {}
-
-  doRefresh(refresher: Refresher) {
-    this.onRefresh.emit(refresher);
-  }
-
-  doInfinite(infiniteScroll) {
-    this.onLoadMore.emit(infiniteScroll);
-  }
-}

+ 0 - 2
src1/components/hashtag/hashtag.html

@@ -1,2 +0,0 @@
-<!-- Generated template for the HashtagComponent component -->
-<span class="hashtag" (click)="search(hashtag)">{{ hashtag }}</span>

+ 0 - 5
src1/components/hashtag/hashtag.scss

@@ -1,5 +0,0 @@
-hashtag {
-  .hashtag {
-    color: color($colors, primary, base);
-  }
-}

+ 0 - 18
src1/components/hashtag/hashtag.ts

@@ -1,18 +0,0 @@
-import { Component, Input } from "@angular/core";
-import { App } from "ionic-angular";
-import { SearchPage } from "../../pages/search/search";
-
-@Component({
-  selector: "hashtag",
-  templateUrl: "hashtag.html"
-})
-export class HashtagComponent {
-  @Input()
-  hashtag;
-
-  constructor(private appCtrl: App) {}
-
-  search(hashtag) {
-    this.appCtrl.getRootNav().push(SearchPage, { query: hashtag });
-  }
-}

+ 0 - 2
src1/components/mention/mention.html

@@ -1,2 +0,0 @@
-<!-- Generated template for the MentionComponent component -->
-<span class="mention" (click)="showProfile(userId)">{{ username }}</span>

+ 0 - 5
src1/components/mention/mention.scss

@@ -1,5 +0,0 @@
-mention {
-  .mention {
-    color: color($colors, primary, base);
-  }
-}

+ 0 - 20
src1/components/mention/mention.ts

@@ -1,20 +0,0 @@
-import { Component, Input } from "@angular/core";
-import { App } from "ionic-angular";
-import { ProfilePage } from "../../pages/profile/profile";
-
-@Component({
-  selector: "mention",
-  templateUrl: "mention.html"
-})
-export class MentionComponent {
-  @Input()
-  username: string;
-  @Input()
-  userId: string;
-
-  constructor(private appCtrl: App) {}
-
-  showProfile(userId) {
-    this.appCtrl.getRootNav().push(ProfilePage, { userId });
-  }
-}

+ 0 - 28
src1/components/profile-header/profile-header.html

@@ -1,28 +0,0 @@
-<!-- Generated template for the ProfileHeaderComponent component -->
-<div>
-  <div class="profile-banner" [style.background-image]="'url('+ banner +')'" [style.background-color]="'#' + user.profile_background_color">
-    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 300 100" xml:space="preserve" width="100%" class="svg-triangle">
-      <polygon points="0,75  0,100 300,100 300,99" fill="#FFFFFF" />
-    </svg>
-    <img src="{{ user.profile_image_url_https | highResolution }}" alt="{{ user.name }}" class="avatar" (click)="showProfilePicture()">
-    <button ion-button color="primary" *ngIf="!user.following" (click)="follow(user.id_str)" class="follow-button">Follow</button>
-    <button ion-button color="danger" *ngIf="user.following" (click)="unfollow(user.id_str)" class="follow-button">Unfollow</button>
-  </div>
-  <div padding>
-    <p class="profile-stats">
-      {{ user.followers_count | friendlyNumber }} Followers |
-      {{ user.friends_count | friendlyNumber }} Following |
-      {{ user.statuses_count | friendlyNumber }} Tweets
-    </p>
-    <p class="profile-description" *ngIf="user.description">{{ user.description }}</p>
-    <div class="profile-infos">
-      <span class="user-location" *ngIf="user.location">
-        <ion-icon name="pin"></ion-icon>&nbsp;{{ user.location }}
-      </span>
-      <span class="user-website" *ngIf="user.url">
-        <ion-icon name="link"></ion-icon>&nbsp;
-        <span [innerHTML]="user.url | replaceUrls: user.entities.url.urls"></span>
-      </span>
-    </div>
-  </div>
-</div>

+ 0 - 25
src1/components/profile-header/profile-header.scss

@@ -1,25 +0,0 @@
-profile-header {
-  .profile-banner {
-    width: 100%;
-    height: calc(100vw * 0.333333333);
-    background-size: cover;
-    position: relative;
-    .svg-triangle {
-      position: absolute;
-      bottom: -1px;
-    }
-  }
-  .avatar {
-    border-radius: 50%;
-    box-shadow: 0px 0px 4px 0px #777;
-    position: absolute;
-    bottom: -15px;
-    left: 15px;
-    width: 90px;
-  }
-  .follow-button {
-    position: absolute;
-    right: 16px;
-    bottom: -8px;
-  }
-}

+ 0 - 45
src1/components/profile-header/profile-header.ts

@@ -1,45 +0,0 @@
-import { Component, Input } from "@angular/core";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-import { PhotoViewer } from "@ionic-native/photo-viewer";
-
-@Component({
-  selector: "profile-header",
-  templateUrl: "profile-header.html"
-})
-export class ProfileHeaderComponent {
-  @Input()
-  user: any;
-
-  constructor(
-    private twitter: TwitterApiProvider,
-    private photoViewer: PhotoViewer
-  ) {}
-
-  get banner() {
-    if (this.user.profile_banner_url) {
-      return this.user.profile_banner_url + "/1500x500";
-    } else {
-      return this.user.profile_background_image_url_https;
-    }
-  }
-
-  async follow(userId) {
-    await this.twitter.createFriendship(userId);
-    this.user.following = true;
-  }
-
-  async unfollow(userId) {
-    await this.twitter.destroyFriendship(userId);
-    this.user.following = false;
-  }
-
-  showProfilePicture() {
-    const profilePicutreHighResUrl = this.user.profile_image_url_https.replace(
-      "_normal",
-      ""
-    );
-    this.photoViewer.show(profilePicutreHighResUrl, this.user.name, {
-      share: true
-    });
-  }
-}

+ 0 - 13
src1/components/quoted-status/quoted-status.html

@@ -1,13 +0,0 @@
-<!-- Generated template for the QuotedStatusComponent component -->
-<div class="quoted-tweet">
-  <div class="header">
-    <img src="{{ data.user.profile_image_url_https }}" alt="{{ data.user.name }}" class="avatar">
-    <span>{{ data.user.name }}</span>
-    <span class="twitter-handle">@{{ data.user.screen_name }}</span>
-    <span class="timestamp">{{ data.created_at | diffForHumans }}</span>
-  </div>
-  <div class="body">
-    <p>{{ data.full_text }}</p>
-    <img *ngIf="hasPhoto" src="{{ data.entities.media[0]['media_url_https'] }}" alt="Photo" (click)="showPhoto(data.entities.media[0]['media_url_https'])">
-  </div>
-</div>

+ 0 - 43
src1/components/quoted-status/quoted-status.scss

@@ -1,43 +0,0 @@
-quoted-status {
-  .quoted-tweet {
-    border: 1px solid #ccc;
-    border-radius: 3px;
-    padding: 5px;
-    margin: 5px 0;
-  }
-  p {
-    white-space: pre-wrap;
-  }
-  .header {
-    display: flex;
-    align-items: center;
-    flex-direction: row;
-    color: #555;
-    font-size: 12px;
-    margin-bottom: 3px;
-    .avatar {
-      border-radius: 50%;
-      width: 28px;
-      margin: 3px 6px 3px 3px;
-    }
-    .twitter-handle {
-      color: #aaa;
-      font-weight: 250;
-      margin-left: 5px;
-    }
-    .timestamp {
-      margin-left: auto;
-      color: #aaa;
-      font-size: 10px;
-    }
-  }
-}
-
-.private quoted-status {
-  .header {
-    color: #efefef;
-  }
-  .body p {
-    color: #efefef;
-  }
-}

+ 0 - 24
src1/components/quoted-status/quoted-status.ts

@@ -1,24 +0,0 @@
-import { Component, Input } from "@angular/core";
-import { PhotoViewer } from "@ionic-native/photo-viewer";
-
-@Component({
-  selector: "quoted-status",
-  templateUrl: "quoted-status.html"
-})
-export class QuotedStatusComponent {
-  @Input()
-  data: any[];
-
-  constructor(private photoViewer: PhotoViewer) {}
-
-  get hasPhoto() {
-    return (
-      this.data["entities"]["media"] &&
-      this.data["entities"]["media"][0]["type"] == "photo"
-    );
-  }
-
-  showPhoto(url: string) {
-    this.photoViewer.show(url, null, { share: true });
-  }
-}

+ 0 - 24
src1/components/tweet-actions/tweet-actions.html

@@ -1,24 +0,0 @@
-<div class="actions-container">
-  <div class="reply" *ngIf="!data.private_tweet" (click)="replyToStatus(data.id_str)">
-    <ion-icon name="undo"></ion-icon>
-  </div>
-  <div class="retweets" *ngIf="!data.user.protected" (click)="retweetStatus(id)">
-    <ion-icon name="ios-git-compare-outline"></ion-icon>
-    <span>{{ data.retweet_count | friendlyNumber }}</span>
-  </div>
-  <div class="likes" *ngIf="!data.private_tweet">
-    <span class="icon-stack" (click)="toggleLike(id)">
-      <ion-icon class="primary-icon" *ngIf="data.favorited" name="ios-heart" color="danger"></ion-icon>
-      <ion-icon class="primary-icon" *ngIf="!data.favorited" name="ios-heart-outline"></ion-icon>
-      <ion-icon class="secondary-icon" name="logo-twitter"></ion-icon>
-    </span>
-    <span>{{ favoriteCount | friendlyNumber }}</span>
-  </div>
-  <div class="private-likes" *ngIf="!data.private_tweet">
-    <span class="icon-stack" (click)="addPrivateLike(id)">
-      <ion-icon class="primary-icon" name="ios-heart-outline"></ion-icon>
-      <ion-icon class="secondary-icon" name="glasses"></ion-icon>
-    </span>
-    <span>{{ privateFavoriteCount | friendlyNumber }}</span>
-  </div>
-</div>

+ 0 - 33
src1/components/tweet-actions/tweet-actions.scss

@@ -1,33 +0,0 @@
-tweet-actions {
-  .actions-container {
-    display: flex;
-    flex-direction: row;
-    div {
-      display: flex;
-      flex-direction: row;
-      align-items: center;
-      justify-content: center;
-      flex-grow: 1;
-      text-align: center;
-      margin-top: 8px;
-      span {
-        margin-left: 5px;
-        font-size: 12px;
-        font-weight: 300;
-        color: #333;
-      }
-    }
-    .icon-stack {
-      position: relative;
-      .secondary-icon {
-        font-size: 0.7em;
-        position: absolute;
-        bottom: 10%;
-        left: 50%;
-        background: #fff;
-        border-radius: 50%;
-        padding: 1px;
-      }
-    }
-  }
-}

+ 0 - 93
src1/components/tweet-actions/tweet-actions.ts

@@ -1,93 +0,0 @@
-import { Component, Input, ChangeDetectorRef } from "@angular/core";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-import { NavController } from "ionic-angular";
-import { WriteTweetPage } from "../../pages/write-tweet/write-tweet";
-import { P2pDatabaseGunProvider } from "../../providers/p2p-database-gun/p2p-database-gun";
-import { Vibration } from "@ionic-native/vibration";
-
-@Component({
-  selector: "tweet-actions",
-  templateUrl: "tweet-actions.html"
-})
-export class TweetActionsComponent {
-  @Input()
-  data: any[];
-  privateFavoriteCount: number = 0;
-
-  constructor(
-    private twitter: TwitterApiProvider,
-    private ref: ChangeDetectorRef,
-    private navCtrl: NavController,
-    private gun: P2pDatabaseGunProvider,
-    private vibration: Vibration
-  ) {}
-
-  ngOnInit() {
-    this.getPrivateLikes(this.id);
-  }
-
-  get favoriteCount() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["favorite_count"];
-    } else {
-      return this.data["favorite_count"];
-    }
-  }
-
-  get id() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["id_str"];
-    } else {
-      return this.data["id_str"];
-    }
-  }
-
-  private async getPrivateLikes(id: string) {
-    const likeEntry = await this.gun.getLikes(this.id);
-    if (likeEntry.likes > 0) {
-      this.privateFavoriteCount = likeEntry.likes;
-      this.ref.detectChanges();
-    }
-  }
-
-  addPrivateLike(id: string) {
-    this.vibration.vibrate([100, 50, 100]);
-    this.gun.addLike(id).then(() => {
-      this.privateFavoriteCount++;
-      this.ref.detectChanges();
-    });
-  }
-
-  toggleLike(id: string) {
-    this.vibration.vibrate([100, 50, 100]);
-    if (this.data["favorited"]) {
-      this.removeLike(id);
-    } else {
-      this.like(id);
-    }
-  }
-
-  private like(id: string): void {
-    this.twitter.likeTweet(id).then(() => {
-      this.data["favorited"] = true;
-      this.data["favorite_count"]++;
-      this.ref.detectChanges();
-    });
-  }
-
-  private removeLike(id: string): void {
-    this.twitter.unlikeTweet(id).then(() => {
-      this.data["favorited"] = false;
-      this.data["favorite_count"]--;
-      this.ref.detectChanges();
-    });
-  }
-
-  retweetStatus(id: string): void {
-    this.navCtrl.push(WriteTweetPage, { tweetId: id });
-  }
-
-  replyToStatus(id: string): void {
-    this.navCtrl.push(WriteTweetPage, { replyToStatus: id });
-  }
-}

+ 0 - 15
src1/components/tweet-body/tweet-body.html

@@ -1,15 +0,0 @@
-<div>
-  <div class="tweet-array">
-    <span class="tweet-array-part" *ngFor="let part of tweetArray">
-      <span *ngIf="part.type =='text'" class="text" [innerHtml]="part.text"></span>
-      <a *ngIf="part.type == 'url'" href="{{ part.url }}">{{part.text}}</a>
-      <mention *ngIf="part.type == 'user_mention'" [username]="part.text" [userId]="part.userId"></mention>
-      <hashtag *ngIf="part.type == 'hashtag'" [hashtag]="part.text"></hashtag>
-    </span>
-  </div>
-
-  <img *ngIf="hasPhoto" src="{{ entities.media[0]['media_url_https'] }}" alt="Photo" class="photo" (click)="showPhoto(entities.media[0]['media_url_https'])">
-  <video *ngIf="isGif" src="{{ extended_entities.media[0]['video_info']['variants'][0]['url'] }}" autoplay loop></video>
-  <quoted-status *ngIf="data.quoted_status" [data]="data.quoted_status"></quoted-status>
-  <div *ngIf="!data.quoted_status && data.quoted_status_id" class="removed-tweet">Tweet has been removed...</div>
-</div>

+ 0 - 22
src1/components/tweet-body/tweet-body.scss

@@ -1,22 +0,0 @@
-tweet-body {
-  span.text {
-    white-space: pre-wrap;
-  }
-  .photo {
-    margin-top: 5px;
-    padding: 2px;
-    border-radius: 3px;
-    border: 1px solid #dfdfdf;
-  }
-  video {
-    width: 100%;
-  }
-  .removed-tweet {
-    border: 1px solid #cc1f1a;
-    padding: 5px;
-    margin: 5px 0;
-    color: #cc1f1a;
-    border-radius: 3px;
-    font-style: italic;
-  }
-}

+ 0 - 204
src1/components/tweet-body/tweet-body.ts

@@ -1,204 +0,0 @@
-import { Component, Input } from "@angular/core";
-import twittertext from "twitter-text";
-import { PhotoViewer } from "@ionic-native/photo-viewer";
-
-@Component({
-  selector: "tweet-body",
-  templateUrl: "tweet-body.html"
-})
-export class TweetBodyComponent {
-  @Input()
-  data: any[];
-
-  constructor(private photoViewer: PhotoViewer) {}
-
-  get full_text(): string {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["full_text"];
-    } else {
-      return this.data["full_text"];
-    }
-  }
-
-  get entities() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["entities"];
-    } else {
-      return this.data["entities"];
-    }
-  }
-
-  get extended_entities() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["extended_entities"];
-    } else {
-      return this.data["extended_entities"];
-    }
-  }
-  get range() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["display_text_range"];
-    } else {
-      return this.data["display_text_range"];
-    }
-  }
-
-  get hasPhoto() {
-    return (
-      !this.data["private_tweet"] &&
-      !this.isGif &&
-      (this.entities["media"] && this.entities["media"][0]["type"] == "photo")
-    );
-  }
-
-  get isGif() {
-    return (
-      !this.data["private_tweet"] &&
-      this.extended_entities &&
-      this.extended_entities["media"] &&
-      this.extended_entities["media"][0]["type"] === "animated_gif"
-    );
-  }
-
-  get status() {
-    // Cut off beginning
-    let status = this.full_text.substring(this.range[0]);
-
-    // Cut off end (URLs)
-    this.urlsToRemoveFromStatus().forEach(
-      url => (status = status.replace(url, ""))
-    );
-
-    return status.trim();
-  }
-
-  get tweetArray() {
-    const extractedEntites = twittertext.extractEntitiesWithIndices(
-      this.status
-    );
-
-    let tweetArray = [];
-    tweetArray = tweetArray.concat(
-      this.getHashtagsForTweetArray(
-        extractedEntites.filter(element => element["hashtag"])
-      )
-    );
-    tweetArray = tweetArray.concat(
-      this.getMentionsForTweetArray(
-        extractedEntites.filter(element => element["screenName"])
-      )
-    );
-    tweetArray = tweetArray.concat(
-      this.getUrlsForTweetArray(
-        extractedEntites.filter(element => element["url"])
-      )
-    );
-    tweetArray = tweetArray.concat(this.getTextParts(tweetArray));
-
-    return tweetArray.sort((a, b) => a["start"] - b["start"]);
-  }
-
-  private urlsToRemoveFromStatus(): string[] {
-    const res = [];
-
-    if (this.data["quoted_status_permalink"]) {
-      res.push(this.data["quoted_status_permalink"]["url"]);
-    }
-
-    if (this.extended_entities) {
-      this.extended_entities["media"].forEach(element => {
-        res.push(element["url"]);
-      });
-    }
-    return res.filter(entry => entry.length);
-  }
-
-  private getHashtagsForTweetArray(hashtags) {
-    const res = [];
-    hashtags.forEach(element => {
-      res.push({
-        start: element.indices[0],
-        stop: element.indices[1],
-        type: "hashtag",
-        text: "#" + element["hashtag"]
-      });
-    });
-    return res;
-  }
-
-  private getMentionsForTweetArray(mentions) {
-    const res = [];
-    mentions.forEach(element => {
-      const apiEntity = this.entities.user_mentions.filter(
-        el =>
-          el.screen_name.toLowerCase() === element["screenName"].toLowerCase()
-      )[0];
-      if (apiEntity) {
-        res.push({
-          start: element.indices[0],
-          stop: element.indices[1],
-          type: "user_mention",
-          text: "@" + element["screenName"],
-          userId: apiEntity["id_str"]
-        });
-      }
-    });
-    return res;
-  }
-
-  private getUrlsForTweetArray(urls) {
-    const res = [];
-    urls.forEach(element => {
-      const apiEntity = this.entities.urls.filter(
-        el => el.url.toLowerCase() === element["url"].toLowerCase()
-      )[0];
-      res.push({
-        start: element.indices[0],
-        stop: element.indices[1],
-        type: "url",
-        url: element["url"],
-        text: apiEntity["display_url"] || element["url"]
-      });
-    });
-    return res;
-  }
-
-  private getTextParts(tweetArray) {
-    const sortedTweetArray = tweetArray.sort((a, b) => a["start"] - b["start"]);
-
-    const textParts = [];
-
-    let prevEnd = 0;
-    for (let i = 0; i < sortedTweetArray.length; i++) {
-      if (sortedTweetArray[i]["start"] !== prevEnd) {
-        const text = this.status.substring(
-          prevEnd,
-          sortedTweetArray[i]["start"]
-        );
-
-        textParts.push({
-          start: prevEnd,
-          stop: sortedTweetArray[i]["start"],
-          type: "text",
-          text: text
-        });
-      }
-      prevEnd = sortedTweetArray[i]["stop"];
-    }
-
-    if (prevEnd != this.status.length) {
-      textParts.push({
-        start: prevEnd,
-        stop: this.status.length,
-        type: "text",
-        text: this.status.substring(prevEnd, this.status.length)
-      });
-    }
-
-    return textParts;
-  }
-
-  showPhoto(url: string) {
-    this.photoViewer.show(url, null, { share: true });
-  }
-}

+ 0 - 14
src1/components/tweet-header/tweet-header.html

@@ -1,14 +0,0 @@
-<!-- Generated template for the TweetHeaderComponent component -->
-<div class="header-container">
-  <img src="{{ user.profile_image_url_https }}" alt="{{ user.name }}" class="avatar" (click)="showProfile(user.id_str)">
-  <div class="username" (click)="showProfile(user.id_str)">
-    <span>
-      {{ user.name }}
-      <ion-icon name="ios-checkmark-circle" *ngIf="user.verified" class="icon-verified"></ion-icon>
-      <ion-icon name="ios-lock-outline" *ngIf="user.protected" class="icon-protected"></ion-icon>
-    </span>
-    <span class="twitter-handle">@{{user.screen_name}}</span>
-  </div>
-  <div class="timestamp">{{ tweetCreatedAt | diffForHumans }}</div>
-  <ion-icon name="ios-arrow-down" class="options" (click)="showActions(user.id_str)"></ion-icon>
-</div>

+ 0 - 39
src1/components/tweet-header/tweet-header.scss

@@ -1,39 +0,0 @@
-tweet-header {
-  .header-container {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    margin-bottom: 4px;
-  }
-  .avatar {
-    border-radius: 50%;
-    width: 32px;
-    height: 32px;
-    box-shadow: 0px 0px 4px 0px #777;
-    margin: 4px 8px 4px 4px;
-  }
-  .username {
-    display: flex;
-    flex-direction: column;
-    font-size: 13px;
-    font-weight: 500;
-    .twitter-handle {
-      color: #aaa;
-      font-size: 10px;
-      font-weight: 400;
-    }
-  }
-  .timestamp {
-    color: #aaa;
-    font-size: 10px;
-    margin-left: auto;
-  }
-  .options {
-    margin-left: 5px;
-    color: #666;
-  }
-  .icon.icon-verified,
-  .icon.icon-protected {
-    font-size: 1em;
-  }
-}

+ 0 - 107
src1/components/tweet-header/tweet-header.ts

@@ -1,107 +0,0 @@
-import { Component, Input } from "@angular/core";
-import { ActionSheetController, App } from "ionic-angular";
-import { ProfilePage } from "../../pages/profile/profile";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-
-@Component({
-  selector: "tweet-header",
-  templateUrl: "tweet-header.html"
-})
-export class TweetHeaderComponent {
-  @Input()
-  user: any[];
-  @Input()
-  tweetCreatedAt: string;
-
-  constructor(
-    private appCtrl: App,
-    public actionSheetCtrl: ActionSheetController,
-    private twitter: TwitterApiProvider
-  ) {}
-
-  showProfile(userId) {
-    this.appCtrl.getRootNav().push(ProfilePage, { userId });
-  }
-
-  showActions(userId) {
-    this.twitter.fetchUser(userId).then(user => {
-      this.actionSheetCtrl
-        .create({
-          title: "@" + this.user["screen_name"],
-          buttons: this.getButtonsForActionSheet(user)
-        })
-        .present();
-    });
-  }
-
-  private getButtonsForActionSheet(user) {
-    const buttons = [];
-    if (user.following) {
-      // Unfollow
-      buttons.push({
-        text: "Unfollow",
-        role: "destructive",
-        handler: () => {
-          this.twitter.destroyFriendship(user.id_str);
-        }
-      });
-    } else {
-      // Follow
-      buttons.push({
-        text: "Follow",
-        role: "destructive",
-        handler: () => {
-          this.twitter.createFriendship(user.id_str);
-        }
-      });
-    }
-
-    if (user.muting) {
-      // unmute
-      buttons.push({
-        text: "Unmute",
-        role: "destructive",
-        handler: () => {
-          this.twitter.unmuteUser(user.id_str);
-        }
-      });
-    } else {
-      // mute
-      buttons.push({
-        text: "Mute",
-        role: "destructive",
-        handler: () => {
-          this.twitter.muteUser(user.id_str);
-        }
-      });
-    }
-
-    if (user.blocking) {
-      // Unblock
-      buttons.push({
-        text: "Unblock",
-        role: "destructive",
-        handler: () => {
-          this.twitter.unblockUser(user.id_str);
-        }
-      });
-    } else {
-      // Block
-      buttons.push({
-        text: "Block",
-        role: "destructive",
-        handler: () => {
-          this.twitter.blockUser(user.id_str);
-        }
-      });
-    }
-
-    // Cancel button
-    buttons.push({
-      text: "Cancel",
-      role: "cancel"
-    });
-
-    return buttons;
-  }
-}

+ 0 - 7
src1/components/tweet/tweet.html

@@ -1,7 +0,0 @@
-<ion-item text-wrap [class.private]="data.private_tweet">
-  <p *ngIf="data.retweeted_status" class="retweet-info">{{ data.user.name }} has retweeted:</p>
-  <p *ngIf="data.in_reply_to_screen_name" class="retweet-info">Reply to @{{ data.in_reply_to_screen_name }}</p>
-  <tweet-header [user]="user" [tweetCreatedAt]="createdAt"></tweet-header>
-  <tweet-body [data]="data"></tweet-body>
-  <tweet-actions [data]="data"></tweet-actions>
-</ion-item>

+ 0 - 23
src1/components/tweet/tweet.scss

@@ -1,23 +0,0 @@
-tweet {
-  .item-md {
-    padding-left: 0;
-  }
-  .item-inner {
-    padding-left: 8px;
-  }
-  .label-md {
-    margin-left: 8px;
-  }
-  .retweet-info {
-    font-weight: 250;
-    font-size: 10px;
-    margin-bottom: 8px;
-  }
-  .private {
-    background: #333;
-    color: #efefef;
-    .retweet-info {
-      color: #bebebe;
-    }
-  }
-}

+ 0 - 34
src1/components/tweet/tweet.ts

@@ -1,34 +0,0 @@
-import { Component, Input } from "@angular/core";
-
-/**
- * Generated class for the TweetComponent component.
- *
- * See https://angular.io/api/core/Component for more info on Angular
- * Components.
- */
-@Component({
-  selector: "tweet",
-  templateUrl: "tweet.html"
-})
-export class TweetComponent {
-  @Input()
-  data: any[];
-
-  constructor() {}
-
-  get user() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["user"];
-    } else {
-      return this.data["user"];
-    }
-  }
-
-  get createdAt() {
-    if (this.data["retweeted_status"]) {
-      return this.data["retweeted_status"]["created_at"];
-    } else {
-      return this.data["created_at"];
-    }
-  }
-}

+ 0 - 51
src1/index.html

@@ -1,51 +0,0 @@
-<!DOCTYPE html>
-<html lang="en" dir="ltr">
-<head>
-  <meta charset="UTF-8">
-  <title>Ionic App</title>
-  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
-  <meta name="format-detection" content="telephone=no">
-  <meta name="msapplication-tap-highlight" content="no">
-
-  <link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
-  <link rel="manifest" href="manifest.json">
-  <meta name="theme-color" content="#4e8ef7">
-
-  <!-- add to homescreen for ios -->
-  <meta name="apple-mobile-web-app-capable" content="yes">
-  <meta name="apple-mobile-web-app-status-bar-style" content="black">
-
-  <!-- cordova.js required for cordova apps (remove if not needed) -->
-  <script src="cordova.js"></script>
-  <script src="assets/scripts/openpgp.js"></script>
-  <script src="assets/scripts/openpgp.worker.js"></script>
-
-  <!-- un-comment this code to enable service worker
-  <script>
-    if ('serviceWorker' in navigator) {
-      navigator.serviceWorker.register('service-worker.js')
-        .then(() => console.log('service worker installed'))
-        .catch(err => console.error('Error', err));
-    }
-  </script>-->
-
-  <link href="build/main.css" rel="stylesheet">
-
-</head>
-<body>
-
-  <!-- Ionic's root component and where the app will load -->
-  <ion-app></ion-app>
-
-  <!-- The polyfills js is generated during the build process -->
-  <script src="build/polyfills.js"></script>
-
-  <!-- The vendor js is generated during the build process
-       It contains all of the dependencies in node_modules -->
-  <script src="build/vendor.js"></script>
-
-  <!-- The main bundle js is generated during the build process -->
-  <script src="build/main.js"></script>
-
-</body>
-</html>

+ 0 - 13
src1/manifest.json

@@ -1,13 +0,0 @@
-{
-  "name": "Ionic",
-  "short_name": "Ionic",
-  "start_url": "index.html",
-  "display": "standalone",
-  "icons": [{
-    "src": "assets/imgs/logo.png",
-    "sizes": "512x512",
-    "type": "image/png"
-  }],
-  "background_color": "#4e8ef7",
-  "theme_color": "#4e8ef7"
-}

+ 0 - 11
src1/pages/about/about.html

@@ -1,11 +0,0 @@
-<ion-header>
-  <ion-navbar>
-    <ion-title>About HybridOSN</ion-title>
-  </ion-navbar>
-</ion-header>
-
-
-<ion-content padding>
-  <p>Hybrid OSN is a hybrid Twitter client for Android. While Twitter can be used as usual, data can also be securely exchanged with other users via a P2P network. Therefore Twitter is not able to analyse, sell or censor this data.</p>
-  <p>Hybrid OSN was developed by Carsten Porth under the supervision of Aidmar Wainakh and Jörg Daubert as part of a master thesis at TU Darmstadt. It is a prototype which was created as proof of concept.</p>
-</ion-content>

+ 0 - 13
src1/pages/about/about.module.ts

@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { IonicPageModule } from 'ionic-angular';
-import { AboutPage } from './about';
-
-@NgModule({
-  declarations: [
-    AboutPage,
-  ],
-  imports: [
-    IonicPageModule.forChild(AboutPage),
-  ],
-})
-export class AboutPageModule {}

+ 0 - 3
src1/pages/about/about.scss

@@ -1,3 +0,0 @@
-page-about {
-
-}

+ 0 - 11
src1/pages/about/about.ts

@@ -1,11 +0,0 @@
-import { Component } from "@angular/core";
-import { IonicPage, NavController, NavParams } from "ionic-angular";
-
-@IonicPage()
-@Component({
-  selector: "page-about",
-  templateUrl: "about.html"
-})
-export class AboutPage {
-  constructor(public navCtrl: NavController, public navParams: NavParams) {}
-}

+ 0 - 18
src1/pages/home/home.html

@@ -1,18 +0,0 @@
-<ion-header>
-  <ion-navbar>
-    <button ion-button menuToggle>
-      <ion-icon name="menu"></ion-icon>
-    </button>
-    <ion-title>Home</ion-title>
-  </ion-navbar>
-</ion-header>
-
-<ion-content>
-  <feed [data]="tweets" (onRefresh)="doRefresh($event)" (onLoadMore)="loadMore($event)"></feed>
-
-  <ion-fab bottom right>
-    <button ion-fab (click)="writeTweet()">
-      <ion-icon name="add"></ion-icon>
-    </button>
-  </ion-fab>
-</ion-content>

+ 0 - 9
src1/pages/home/home.module.ts

@@ -1,9 +0,0 @@
-import { NgModule } from "@angular/core";
-import { IonicPageModule } from "ionic-angular";
-import { HomePage } from "./home";
-
-@NgModule({
-  declarations: [HomePage],
-  imports: [IonicPageModule.forChild(HomePage)]
-})
-export class HomePageModule {}

+ 0 - 0
src1/pages/home/home.scss


+ 0 - 91
src1/pages/home/home.ts

@@ -1,91 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  MenuController,
-  InfiniteScroll,
-  Refresher,
-  LoadingController
-} from "ionic-angular";
-import { WriteTweetPage } from "../write-tweet/write-tweet";
-import { FeedProvider } from "../../providers/feed/feed";
-
-@IonicPage()
-@Component({
-  selector: "page-home",
-  templateUrl: "home.html"
-})
-export class HomePage {
-  menuController: MenuController;
-  tweets;
-
-  constructor(
-    public navCtrl: NavController,
-    private menuCtrl: MenuController,
-    private feed: FeedProvider,
-    private loadingCtrl: LoadingController
-  ) {}
-
-  ionViewDidLoad() {
-    this.menuCtrl.enable(true, "sideNav");
-  }
-
-  ionViewDidEnter() {
-    const loading = this.loadingCtrl.create();
-    loading.present();
-
-    this.feed
-      .loadHomeTimeline()
-      .then(tweets => (this.tweets = tweets))
-      .catch(err => console.error(err))
-      .then(() => loading.dismiss());
-  }
-
-  doRefresh(refresher: Refresher) {
-    this.feed.loadHomeTimeline().then(tweets => {
-      this.tweets = tweets;
-      refresher.complete();
-    });
-  }
-
-  loadMore(infiniteScroll: InfiniteScroll) {
-    this.feed
-      .loadHomeTimeline(this.oldestPublicTweet, this.oldestPrivateTweet)
-      .then(tweets => {
-        this.tweets = this.tweets.concat(tweets);
-        infiniteScroll.complete();
-      });
-  }
-
-  writeTweet() {
-    this.navCtrl.push(WriteTweetPage);
-  }
-
-  get publicTweets() {
-    return this.tweets.filter(tweet => !tweet.private_tweet);
-  }
-
-  get privateTweets() {
-    return this.tweets.filter(tweet => tweet.private_tweet);
-  }
-
-  get oldestPublicTweet() {
-    if (this.publicTweets.length > 0) {
-      return this.publicTweets.reduce((acc, cur) =>
-        acc.id < cur.id ? acc : cur
-      );
-    } else {
-      return undefined;
-    }
-  }
-
-  get oldestPrivateTweet() {
-    if (this.privateTweets.length > 0) {
-      return this.privateTweets.reduce((acc, cur) =>
-        new Date(acc.created_at) < new Date(cur.created_at) ? acc : cur
-      );
-    } else {
-      return undefined;
-    }
-  }
-}

+ 0 - 13
src1/pages/login/login.html

@@ -1,13 +0,0 @@
-<ion-content>
-  <div class="header"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 300 100" xml:space="preserve" width="100%" class="svg-triangle">
-      <polygon points="0,99  0,100 300,100 300,75" fill="#FFFFFF" /></svg>
-    <div class="logo">
-      <img src="assets/imgs/logo.png" alt="Logo">
-    </div>
-  </div>
-  <div class="content">
-    <h1>Hybrid OSN</h1>
-    <button ion-button outline block (click)="login()">Login</button>
-    <a href="#" (click)="showAbout()">Learn more</a>
-  </div>
-</ion-content>

+ 0 - 9
src1/pages/login/login.module.ts

@@ -1,9 +0,0 @@
-import { NgModule } from "@angular/core";
-import { IonicPageModule } from "ionic-angular";
-import { LoginPage } from "./login";
-
-@NgModule({
-  declarations: [LoginPage],
-  imports: [IonicPageModule.forChild(LoginPage)]
-})
-export class LoginPageModule {}

+ 0 - 33
src1/pages/login/login.scss

@@ -1,33 +0,0 @@
-page-login {
-  .header {
-    background: url("../assets/imgs/background-login-sm.png") repeat #5ec0f9;
-    width: 100%;
-    height: 40vh;
-    position: relative;
-    margin-bottom: 50px;
-    .logo {
-      width: 140px;
-      height: 140px;
-      position: absolute;
-      bottom: -60px;
-      left: calc(50% - 70px);
-      img {
-        border-radius: 50%;
-        border: 5px solid #fff;
-      }
-    }
-    .svg-triangle {
-      position: absolute;
-      bottom: 0;
-    }
-  }
-  .content {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    padding: 16px;
-    button {
-      margin: 16px 0 32px 0;
-    }
-  }
-}

+ 0 - 53
src1/pages/login/login.ts

@@ -1,53 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  NavParams,
-  MenuController,
-  AlertController,
-  ModalController,
-  Events
-} from "ionic-angular";
-import { AuthProvider } from "../../providers/auth/auth";
-import { AboutPage } from "../about/about";
-import { HomePage } from "../home/home";
-
-@IonicPage()
-@Component({
-  selector: "page-login",
-  templateUrl: "login.html"
-})
-export class LoginPage {
-  constructor(
-    public navCtrl: NavController,
-    public navParams: NavParams,
-    private menuCtrl: MenuController,
-    private alertCtrl: AlertController,
-    private authProvider: AuthProvider,
-    private modalCtrl: ModalController,
-    private events: Events
-  ) {}
-
-  ionViewDidLoad() {
-    this.menuCtrl.enable(false, "sideNav");
-  }
-
-  login() {
-    const alertText = {
-      title: "Login failed",
-      subTitle:
-        "Somthing went wrong while trying to log you in. Please try again.",
-      buttons: ["OK"]
-    };
-
-    this.authProvider
-      .login()
-      .then(() => this.events.publish("user:login"))
-      .then(() => this.navCtrl.setRoot(HomePage))
-      .catch(err => this.alertCtrl.create(alertText).present());
-  }
-
-  showAbout() {
-    this.modalCtrl.create(AboutPage).present();
-  }
-}

+ 0 - 15
src1/pages/profile/profile.html

@@ -1,15 +0,0 @@
-<ion-header>
-  <ion-navbar>
-    <ion-title>
-      {{ user.name }}
-      <ion-icon name="ios-checkmark-circle" *ngIf="user.verified" class="icon-verified"></ion-icon>
-      <ion-icon name="ios-lock-outline" *ngIf="user.protected" class="icon-protected"></ion-icon>
-    </ion-title>
-  </ion-navbar>
-</ion-header>
-
-<ion-content fullscreen (ionScroll)="onScroll($event)">
-  <profile-header [user]="user"></profile-header>
-  <feed [data]="tweets" (onRefresh)="doRefresh($event)" (onLoadMore)="loadMore($event)" [enableRefresh]="enableRefresh"
-    [enableInfiniteScroll]="enableInfiniteScroll"></feed>
-</ion-content>

+ 0 - 9
src1/pages/profile/profile.module.ts

@@ -1,9 +0,0 @@
-import { NgModule } from "@angular/core";
-import { IonicPageModule } from "ionic-angular";
-import { ProfilePage } from "./profile";
-
-@NgModule({
-  declarations: [ProfilePage],
-  imports: [IonicPageModule.forChild(ProfilePage)]
-})
-export class ProfilePageModule {}

+ 0 - 3
src1/pages/profile/profile.scss

@@ -1,3 +0,0 @@
-ion-navbar .icon {
-    font-size: 2rem;
-}

+ 0 - 128
src1/pages/profile/profile.ts

@@ -1,128 +0,0 @@
-import { Component, ViewChild } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  NavParams,
-  InfiniteScroll,
-  Content,
-  LoadingController
-} from "ionic-angular";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-import { FeedProvider } from "../../providers/feed/feed";
-
-@IonicPage()
-@Component({
-  selector: "page-profile",
-  templateUrl: "profile.html"
-})
-export class ProfilePage {
-  user: any = [];
-  tweets: any[];
-  oldestLoadedTweetId;
-  enableRefresh: boolean = true;
-  enableInfiniteScroll: boolean = true;
-
-  @ViewChild(Content)
-  content: Content;
-
-  constructor(
-    public navCtrl: NavController,
-    private loadingCtrl: LoadingController,
-    private navParams: NavParams,
-    private twitter: TwitterApiProvider,
-    private feed: FeedProvider
-  ) {}
-
-  ionViewDidLoad() {
-    // Show loading indicator
-    const loading = this.loadingCtrl.create();
-    loading.present();
-
-    // Read user id
-    const userId = this.navParams.get("userId");
-
-    // Fetch user details from Twitter
-    this.twitter.fetchUser(userId).then(res => (this.user = res));
-
-    // Load user's timeline from Twitter and P2P
-    this.feed.loadUserTimeline(userId).then(res => {
-      if (res.length > 0) {
-        // Store tweets
-        this.tweets = res;
-      } else {
-        this.enableInfiniteScroll = false;
-      }
-      // Hide loading indicator
-      loading.dismiss();
-    });
-  }
-
-  doRefresh(refresher) {
-    this.feed.loadUserTimeline(this.user.id_str).then(res => {
-      if (res.length > 0) {
-        // Replace tweets
-        this.tweets = res;
-      }
-
-      // Hide loading icon
-      refresher.complete();
-    });
-  }
-
-  loadMore(infiniteScroll: InfiniteScroll) {
-    if (this.enableInfiniteScroll) {
-      this.feed
-        .loadUserTimeline(
-          this.user.id_str,
-          this.oldestPublicTweet,
-          this.oldestPrivateTweet
-        )
-        .then(res => {
-          if (res.length > 0) {
-            // Append loaded tweets
-            this.tweets = this.tweets.concat(res);
-          } else {
-            this.enableInfiniteScroll = false;
-          }
-          // Hide loading icon
-          infiniteScroll.complete();
-        });
-    } else {
-      // Hide loading icon
-      infiniteScroll.complete();
-    }
-  }
-
-  get publicTweets() {
-    return this.tweets.filter(tweet => !tweet.private_tweet);
-  }
-
-  get privateTweets() {
-    return this.tweets.filter(tweet => tweet.private_tweet);
-  }
-
-  get oldestPublicTweet() {
-    if (this.publicTweets.length > 0) {
-      return this.publicTweets.reduce(
-        (acc, cur) => (acc.id < cur.id ? acc : cur)
-      );
-    } else {
-      return undefined;
-    }
-  }
-
-  get oldestPrivateTweet() {
-    if (this.privateTweets.length > 0) {
-      return this.privateTweets.reduce(
-        (acc, cur) =>
-          new Date(acc.created_at) < new Date(cur.created_at) ? acc : cur
-      );
-    } else {
-      return undefined;
-    }
-  }
-
-  onScroll(event) {
-    this.enableRefresh = event.scrollTop === 0;
-  }
-}

+ 0 - 4
src1/pages/search-results-tweets-popular/search-results-tweets-popular.html

@@ -1,4 +0,0 @@
-<ion-content no-padding>
-  <feed [data]="tweets.statuses" (onRefresh)="doRefresh($event)" (onLoadMore)="loadMore($event)" [enableRefresh]="enableRefresh"
-    [enableInfiniteScroll]="enableInfiniteScroll"></feed>
-</ion-content>

+ 0 - 13
src1/pages/search-results-tweets-popular/search-results-tweets-popular.module.ts

@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { IonicPageModule } from 'ionic-angular';
-import { SearchResultsTweetsPopularPage } from './search-results-tweets-popular';
-
-@NgModule({
-  declarations: [
-    SearchResultsTweetsPopularPage,
-  ],
-  imports: [
-    IonicPageModule.forChild(SearchResultsTweetsPopularPage),
-  ],
-})
-export class SearchResultsTweetsPopularPageModule {}

+ 0 - 5
src1/pages/search-results-tweets-popular/search-results-tweets-popular.scss

@@ -1,5 +0,0 @@
-page-search-results-tweets-popular {
-    feed .scroll-content {
-        margin-top: 0 !important;
-    }
-}

+ 0 - 80
src1/pages/search-results-tweets-popular/search-results-tweets-popular.ts

@@ -1,80 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  NavParams,
-  Refresher,
-  InfiniteScroll,
-  Events
-} from "ionic-angular";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-
-@IonicPage()
-@Component({
-  selector: "page-search-results-tweets-popular",
-  templateUrl: "search-results-tweets-popular.html"
-})
-export class SearchResultsTweetsPopularPage {
-  query: string;
-  tweets = [];
-
-  constructor(
-    public navCtrl: NavController,
-    public navParams: NavParams,
-    private twitter: TwitterApiProvider,
-    private events: Events
-  ) {
-    this.query = this.navParams.data;
-
-    this.events.subscribe("query:changed", query => {
-      if (query.length) {
-        this.twitter
-          .searchPopularTweets(query)
-          .then(res => (this.tweets = res));
-        this.query = query;
-      }
-    });
-  }
-
-  async ionViewDidLoad() {
-    if (this.query.length) {
-      this.tweets = await this.twitter.searchPopularTweets(this.query);
-    }
-  }
-
-  doRefresh(refresher: Refresher) {
-    this.twitter.searchPopularTweets(this.query).then(tweets => {
-      this.tweets = tweets;
-      refresher.complete();
-    });
-  }
-
-  loadMore(infiniteScroll: InfiniteScroll) {
-    this.twitter
-      .searchPopularTweets(this.query, this.oldestTweet)
-      .then(tweets => {
-        this.tweets["statuses"] = this.tweets["statuses"].concat(
-          tweets["statuses"]
-        );
-        infiniteScroll.complete();
-      });
-  }
-
-  get oldestTweet() {
-    if (this.tweets.length > 0) {
-      return this.tweets.reduce((acc, cur) => (acc.id < cur.id ? acc : cur))[
-        "id_str"
-      ];
-    } else {
-      return undefined;
-    }
-  }
-
-  get enableRefresh() {
-    return this.query.length > 0;
-  }
-
-  get enableInfiniteScroll() {
-    return this.query.length > 0;
-  }
-}

+ 0 - 4
src1/pages/search-results-tweets-recent/search-results-tweets-recent.html

@@ -1,4 +0,0 @@
-<ion-content no-padding>
-  <feed [data]="tweets.statuses" (onRefresh)="doRefresh($event)" (onLoadMore)="loadMore($event)" [enableRefresh]="enableRefresh"
-    [enableInfiniteScroll]="enableInfiniteScroll"></feed>
-</ion-content>

+ 0 - 13
src1/pages/search-results-tweets-recent/search-results-tweets-recent.module.ts

@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { IonicPageModule } from 'ionic-angular';
-import { SearchResultsTweetsRecentPage } from './search-results-tweets-recent';
-
-@NgModule({
-  declarations: [
-    SearchResultsTweetsRecentPage,
-  ],
-  imports: [
-    IonicPageModule.forChild(SearchResultsTweetsRecentPage),
-  ],
-})
-export class SearchResultsTweetsRecentPageModule {}

+ 0 - 5
src1/pages/search-results-tweets-recent/search-results-tweets-recent.scss

@@ -1,5 +0,0 @@
-page-search-results-tweets-recent {
-    feed .scroll-content {
-        margin-top: 0 !important;
-    }
-}

+ 0 - 78
src1/pages/search-results-tweets-recent/search-results-tweets-recent.ts

@@ -1,78 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  NavParams,
-  Refresher,
-  InfiniteScroll,
-  Events
-} from "ionic-angular";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-
-@IonicPage()
-@Component({
-  selector: "page-search-results-tweets-recent",
-  templateUrl: "search-results-tweets-recent.html"
-})
-export class SearchResultsTweetsRecentPage {
-  query: string;
-  tweets = [];
-
-  constructor(
-    public navCtrl: NavController,
-    public navParams: NavParams,
-    private twitter: TwitterApiProvider,
-    private events: Events
-  ) {
-    this.query = this.navParams.data;
-
-    this.events.subscribe("query:changed", query => {
-      if (query.length) {
-        this.twitter.searchRecentTweets(query).then(res => (this.tweets = res));
-        this.query = query;
-      }
-    });
-  }
-
-  async ionViewDidLoad() {
-    if (this.query.length) {
-      this.tweets = await this.twitter.searchRecentTweets(this.query);
-    }
-  }
-
-  doRefresh(refresher: Refresher) {
-    this.twitter.searchRecentTweets(this.query).then(tweets => {
-      this.tweets = tweets;
-      refresher.complete();
-    });
-  }
-
-  loadMore(infiniteScroll: InfiniteScroll) {
-    this.twitter
-      .searchRecentTweets(this.query, this.oldestTweet)
-      .then(tweets => {
-        this.tweets["statuses"] = this.tweets["statuses"].concat(
-          tweets["statuses"]
-        );
-        infiniteScroll.complete();
-      });
-  }
-
-  get oldestTweet() {
-    if (this.tweets.length > 0) {
-      return this.tweets.reduce((acc, cur) => (acc.id < cur.id ? acc : cur))[
-        "id_str"
-      ];
-    } else {
-      return undefined;
-    }
-  }
-
-  get enableRefresh() {
-    return this.query.length > 0;
-  }
-
-  get enableInfiniteScroll() {
-    return this.query.length > 0;
-  }
-}

+ 0 - 6
src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.html

@@ -1,6 +0,0 @@
-<ion-content no-padding>
-  <ion-tabs selectedIndex="0" tabsPlacement="top">
-    <ion-tab [root]="searchResultsRecentTweets" [rootParams]="query" tabTitle="Recent"></ion-tab>
-    <ion-tab [root]="searchResultsPopularTweets" [rootParams]="query" tabTitle="Popular"></ion-tab>
-  </ion-tabs>
-</ion-content>

+ 0 - 13
src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.module.ts

@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { IonicPageModule } from 'ionic-angular';
-import { SearchResultsTweetsTabsPage } from './search-results-tweets-tabs';
-
-@NgModule({
-  declarations: [
-    SearchResultsTweetsTabsPage,
-  ],
-  imports: [
-    IonicPageModule.forChild(SearchResultsTweetsTabsPage),
-  ],
-})
-export class SearchResultsTweetsTabsPageModule {}

+ 0 - 2
src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.scss

@@ -1,2 +0,0 @@
-page-search-results-tweets-tabs {
-}

+ 0 - 21
src1/pages/search-results-tweets-tabs/search-results-tweets-tabs.ts

@@ -1,21 +0,0 @@
-import { Component } from "@angular/core";
-import { IonicPage, NavController, NavParams } from "ionic-angular";
-import { SearchResultsTweetsRecentPage } from "../search-results-tweets-recent/search-results-tweets-recent";
-import { SearchResultsTweetsPopularPage } from "../search-results-tweets-popular/search-results-tweets-popular";
-
-@IonicPage()
-@Component({
-  selector: "page-search-results-tweets-tabs",
-  templateUrl: "search-results-tweets-tabs.html"
-})
-export class SearchResultsTweetsTabsPage {
-  searchResultsRecentTweets = SearchResultsTweetsRecentPage;
-  searchResultsPopularTweets = SearchResultsTweetsPopularPage;
-  query: string;
-
-  constructor(public navCtrl: NavController, public navParams: NavParams) {
-    this.query = this.navParams.data;
-  }
-
-  ionViewDidLoad() {}
-}

+ 0 - 24
src1/pages/search-results-users/search-results-users.html

@@ -1,24 +0,0 @@
-<ion-content no-padding fullscreen>
-  <ion-refresher (ionRefresh)="doRefresh($event)" enabled="query.length">
-    <ion-refresher-content pullingText=" Pull to refresh" refreshingText="Refreshing...">
-    </ion-refresher-content>
-  </ion-refresher>
-
-  <ion-list>
-    <ion-item *ngFor="let user of users" (click)="showProfile(user.id_str)">
-      <ion-avatar item-start>
-        <img src="{{ user.profile_image_url_https }}">
-      </ion-avatar>
-      <h2>
-        {{ user.name }}
-        <ion-icon name="ios-checkmark-circle" *ngIf="user.verified" class="icon-verified"></ion-icon>
-        <ion-icon name="ios-lock-outline" *ngIf="user.protected" class="icon-protected"></ion-icon>
-      </h2>
-      <p>@{{ user.screen_name }}</p>
-    </ion-item>
-  </ion-list>
-
-  <ion-infinite-scroll (ionInfinite)="loadMore($event)" enabled="query.length">
-    <ion-infinite-scroll-content loadingText="Loading more users..."></ion-infinite-scroll-content>
-  </ion-infinite-scroll>
-</ion-content>

+ 0 - 13
src1/pages/search-results-users/search-results-users.module.ts

@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { IonicPageModule } from 'ionic-angular';
-import { SearchResultsUsersPage } from './search-results-users';
-
-@NgModule({
-  declarations: [
-    SearchResultsUsersPage,
-  ],
-  imports: [
-    IonicPageModule.forChild(SearchResultsUsersPage),
-  ],
-})
-export class SearchResultsUsersPageModule {}

+ 0 - 6
src1/pages/search-results-users/search-results-users.scss

@@ -1,6 +0,0 @@
-page-search-results-users {
-  .icon-verified,
-  .icon-protected {
-    font-size: 1em;
-  }
-}

+ 0 - 67
src1/pages/search-results-users/search-results-users.ts

@@ -1,67 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  NavParams,
-  Refresher,
-  InfiniteScroll,
-  App,
-  Events
-} from "ionic-angular";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-import { ProfilePage } from "../profile/profile";
-
-@IonicPage()
-@Component({
-  selector: "page-search-results-users",
-  templateUrl: "search-results-users.html"
-})
-export class SearchResultsUsersPage {
-  query: string;
-  nextPage: number = 2;
-  users: any[] = [];
-
-  constructor(
-    public navCtrl: NavController,
-    public navParams: NavParams,
-    private appCtrl: App,
-    private twitter: TwitterApiProvider,
-    private events: Events
-  ) {
-    this.query = this.navParams.data;
-
-    this.events.subscribe("query:changed", query => {
-      if (query.length) {
-        this.twitter.searchUsers(query).then(res => (this.users = res));
-        this.query = query;
-      }
-    });
-  }
-
-  async ionViewDidLoad() {
-    if (this.query.length) {
-      this.users = await this.twitter.searchUsers(this.query);
-    }
-  }
-
-  showProfile(userId) {
-    this.appCtrl.getRootNav().push(ProfilePage, { userId });
-    this.nextPage = 2;
-  }
-
-  doRefresh(refresher: Refresher) {
-    this.twitter.searchUsers(this.query).then(users => {
-      this.users = users;
-      this.nextPage = 2;
-      refresher.complete();
-    });
-  }
-
-  loadMore(infiniteScroll: InfiniteScroll) {
-    this.twitter.searchUsers(this.query, this.nextPage).then(users => {
-      this.users = this.users.concat(users);
-      infiniteScroll.complete();
-      this.nextPage = this.nextPage + 1;
-    });
-  }
-}

+ 0 - 13
src1/pages/search/search.html

@@ -1,13 +0,0 @@
-<ion-header>
-    <ion-navbar><button ion-button menuToggle>
-            <ion-icon name="menu"></ion-icon>
-        </button>
-        <ion-searchbar [(ngModel)]="query" (ionInput)="onInput()" debounce="500"></ion-searchbar>
-    </ion-navbar>
-</ion-header>
-<ion-content no-padding>
-    <ion-tabs selectedIndex="0" tabsLayout="icon-start" tabsPlacement="bottom">
-        <ion-tab [root]="searchResultsTweets" [rootParams]="query" tabTitle="Tweets" tabIcon="logo-twitter"></ion-tab>
-        <ion-tab [root]="searchResultsUsers" [rootParams]="query" tabTitle="Users" tabIcon="person"></ion-tab>
-    </ion-tabs>
-</ion-content>

+ 0 - 0
src1/pages/search/search.scss


+ 0 - 26
src1/pages/search/search.ts

@@ -1,26 +0,0 @@
-import { Component } from "@angular/core";
-import { NavController, NavParams, Events } from "ionic-angular";
-import { SearchResultsUsersPage } from "../search-results-users/search-results-users";
-import { SearchResultsTweetsTabsPage } from "../search-results-tweets-tabs/search-results-tweets-tabs";
-
-@Component({
-  selector: "page-search",
-  templateUrl: "search.html"
-})
-export class SearchPage {
-  searchResultsTweets = SearchResultsTweetsTabsPage;
-  searchResultsUsers = SearchResultsUsersPage;
-  query: string;
-
-  constructor(
-    public navCtrl: NavController,
-    private navParams: NavParams,
-    private events: Events
-  ) {
-    this.query = this.navParams.get("query");
-  }
-
-  onInput() {
-    this.events.publish("query:changed", this.query.trim());
-  }
-}

+ 0 - 40
src1/pages/settings/settings.html

@@ -1,40 +0,0 @@
-<ion-header>
-  <ion-navbar>
-    <button ion-button menuToggle>
-      <ion-icon name="menu"></ion-icon>
-    </button>
-    <ion-title>Settings</ion-title>
-  </ion-navbar>
-</ion-header>
-
-<ion-content padding>
-  <ion-card>
-    <ion-card-header>Keywords for Private Mode</ion-card-header>
-    <ion-card-content>
-      <p>The following hashtags will automatically activate the private mode when liking or writing a tweet.</p>
-      <ion-label color="primary" stacked>Keywords:</ion-label>
-      <ion-textarea [(ngModel)]="keywords"></ion-textarea>
-    </ion-card-content>
-  </ion-card>
-
-  <ion-card>
-    <ion-card-header>Encryption</ion-card-header>
-    <ion-card-content>
-      <p>To protect your privacy, all data send to the P2P network will be encrypted. Therefore you need to enter or
-        generate
-        a pair of keys. If you run the app on multiple devices, please enter everywhere the same pair of keys.</p>
-      <ion-label color="primary" stacked>Enter your email address:</ion-label>
-      <ion-input [(ngModel)]="email" type="email" required></ion-input>
-      <button ion-button block (click)="generateKeys()">Generate keys</button>
-      <ion-label color="primary" stacked>Private Key:</ion-label>
-      <ion-textarea [(ngModel)]="privateKey"></ion-textarea>
-      <ion-label color="primary" stacked>Public Key:</ion-label>
-      <ion-textarea [(ngModel)]="publicKey"></ion-textarea>
-      <p>Under no circumstances share your private key with any other person!</p>
-      <button ion-button block (click)="publishPublicKey()">Publish public key</button>
-      <button ion-button block (click)="exportPrivateKey()">Export private key</button>
-    </ion-card-content>
-  </ion-card>
-
-  <button ion-button block (click)="save()">Save settings</button>
-</ion-content>

+ 0 - 0
src1/pages/settings/settings.scss


+ 0 - 151
src1/pages/settings/settings.ts

@@ -1,151 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  NavController,
-  ToastController,
-  LoadingController,
-  AlertController
-} from "ionic-angular";
-import { Storage } from "@ionic/storage";
-import { CryptoProvider } from "../../providers/crypto/crypto";
-import { SocialSharing } from "@ionic-native/social-sharing";
-import * as openpgp from 'openpgp';
-
-@Component({
-  selector: "page-settings",
-  templateUrl: "settings.html"
-})
-export class SettingsPage {
-  keywords: string;
-  privateKey: string;
-  publicKey: string;
-  email: string;
-  hkp = new openpgp.HKP('https://sks-keyservers.net/');
-
-  constructor(
-    public navCtrl: NavController,
-    public toastCtrl: ToastController,
-    private cryptoUtils: CryptoProvider,
-    private storage: Storage,
-    private loadingCtrl: LoadingController,
-    private sharing: SocialSharing,
-    private alertCtrl: AlertController
-  ) {
-    this.loadValuesFromStorage();
-  }
-
-  async loadValuesFromStorage() {
-    this.privateKey = await this.storage.get("privateKey");
-    this.publicKey = await this.storage.get("publicKey");
-    this.keywords = await this.storage.get("keywords");
-    this.email = await this.storage.get("email");
-  }
-
-  generateKeys() {
-    if (!this.email){
-          console.log("email is not provided or not valid");
-          return;
-    }
-    else{
-      this.storage.set("email", this.email);
-      if (this.publicKey || this.privateKey) {
-        const alert = this.alertCtrl.create({
-          title: "Are you sure?",
-          subTitle:
-            "You already have keys entered. Do you want to overwrite them?",
-          buttons: [
-            {
-              text: "No",
-              role: "cancel"
-            },
-            {
-              text: "Yes",
-              handler: () => {
-                this.startKeyGeneration();
-              }
-            }
-          ]
-        });
-
-        alert.present();
-      } else {
-        this.startKeyGeneration();
-      }
-    }
-  }
-
-  private async startKeyGeneration() {
-    const keys = await this.cryptoUtils.generatePgpKeys(this.email);
-    
-    this.privateKey = keys.privateKeyArmored;
-    this.publicKey = keys.publicKeyArmored;
-    console.log("public key", this.privateKey);
-    console.log("public key", this.publicKey);
-    // this.privateKey = await this.cryptoUtils.extractPrivateKey(keys);
-  }
-
-  save() {
-    this.storage.set("publicKey", this.publicKey);
-    this.storage.set("privateKey", this.privateKey);
-    this.storage.set("keywords", this.keywords ? this.keywords.trim() : "");
-
-    this.showToast("Successfully saved!");
-  }
-
-  async publishPublicKey() {    
-    await this.publishPublicKey2();
-    await this.lookupKeys(this.email);
-  }
-  
-  async publishPublicKey2() {      
-    const loading = this.loadingCtrl.create();
-      loading.present();
-      // console.log("Uploding publish public key", this.publicKey);
-      if(!this.publicKey) return;
-      this.hkp.upload(this.publicKey).then(function() {
-        console.log("Uploding public key");
-      });
-      loading.dismiss();
-      this.showToast("Public key has been published!");
-      //lookup key to verify it has been pubblished
-      // await this.lookupKeys(this.email);
-  }
-
-  public async lookupKeys(email:string){
-
-    var options = {
-        query: email
-    };
-
-    let armoredPubkey = await this.hkp.lookup(options);
-    let pubkey = await openpgp.key.readArmored(armoredPubkey);
-
-     console.log('Found public key:',pubkey);
-     // if(! (email == 'rohit.hosn@gmail.com'))
-     //   this.pk.push(pubkey.publicKeyArmored);
-     // return pubkey;
-  }
-
-  exportPrivateKey() {
-    if (this.privateKey.length) {
-      this.sharing
-        .share(this.privateKey, null, null, null)
-        .then(() => console.log("Private key was exported"))
-        .catch(() =>
-          this.showToast(
-            "Sorry! Something went wrong trying to export the private key :("
-          )
-        );
-    } else {
-      this.showToast("There is nothing to share.");
-    }
-  }
-
-  private showToast(message: string) {
-    const toast = this.toastCtrl.create({
-      message: message,
-      position: "bottom",
-      duration: 3000
-    });
-    toast.present();
-  }
-}

+ 0 - 45
src1/pages/write-tweet/write-tweet.html

@@ -1,45 +0,0 @@
-<ion-header>
-  <ion-navbar>
-    <ion-title>Tweet something</ion-title>
-  </ion-navbar>
-</ion-header>
-
-<ion-content padding>
-  <!-- Show tweet to retweet or quote (if passed to the page) -->
-  <ion-label *ngIf="retweet" color="primary">Retweet</ion-label>
-  <quoted-status *ngIf="retweet" [data]="retweet.data"></quoted-status>
-
-  <!-- Show tweet to reply to -->
-  <ion-label *ngIf="replyTweet" color="primary">Reply to</ion-label>
-  <quoted-status *ngIf="replyTweet" [data]="replyTweet.data"></quoted-status>
-
-  <!-- Form to write a tweet -->
-  <form [formGroup]="tweet" (ngSubmit)="submitTweet()">
-    <ion-item class="padding-0">
-      <ion-label color="primary" stacked>Your tweet</ion-label>
-      <ion-textarea type="text" formControlName="text" maxlength="140" [attr.rows]="4"></ion-textarea>
-    </ion-item>
-
-    <div class="actions">
-      <span class="progress">
-        <svg width="20" height="20" class="progress-circle">
-          <circle class="background-stroke" cx="10" cy="10" r="8"></circle>
-          <circle class="progress-stroke" cx="10" cy="10" r="8" transform="rotate(-90, 10, 10)" [style.strokeDashoffset]="tweetCharProgress"></circle>
-        </svg>
-
-        <span class="progress-stats">{{ (tweet.value.text).length }}/140</span>
-      </span>
-
-      <span class="network-switch">
-        <ion-icon name="logo-twitter"></ion-icon>
-        <ion-toggle checked="false" formControlName="p2p" color="dark"></ion-toggle>
-        <ion-icon name="glasses"></ion-icon>
-      </span>
-
-      <ion-icon name="warning" *ngIf="showTrigger" class="warning" (click)="showTriggerInfo()"></ion-icon>
-
-      <button ion-button type="submit" class="submit-tweet">tweet!</button>
-    </div>
-  </form>
-
-</ion-content>

+ 0 - 9
src1/pages/write-tweet/write-tweet.module.ts

@@ -1,9 +0,0 @@
-import { NgModule } from "@angular/core";
-import { IonicPageModule } from "ionic-angular";
-import { WriteTweetPage } from "./write-tweet";
-
-@NgModule({
-  declarations: [WriteTweetPage],
-  imports: [IonicPageModule.forChild(WriteTweetPage)]
-})
-export class WriteTweetPageModule {}

+ 0 - 53
src1/pages/write-tweet/write-tweet.scss

@@ -1,53 +0,0 @@
-page-write-tweet {
-  .padding-0 {
-    padding: 0;
-  }
-  .actions {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    justify-content: space-between;
-    .progress {
-      display: flex;
-      align-items: center;
-      .progress-stats {
-        margin-left: 5px;
-      }
-      .background-stroke,
-      .progress-stroke {
-        fill: transparent;
-        stroke-width: 2;
-        stroke-dasharray: 50.2654825;
-        transition: stroke-dashoffset 0.5s;
-        -webkit-animation-play-state: running;
-      }
-      .background-stroke {
-        stroke: #ddd;
-      }
-      .progress-stroke {
-        stroke: blue;
-      }
-    }
-    .network-switch {
-      display: flex;
-      align-items: center;
-      margin-left: 16px;
-    }
-  }
-  ion-icon.warning {
-    color: orange;
-    animation: pulse 1.8s infinite;
-  }
-}
-
-@keyframes pulse {
-  0% {
-    transform: scale(1);
-  }
-  50% {
-    transform: scale(1.3);
-  }
-  100% {
-    transform: scale(1);
-  }
-}

+ 0 - 379
src1/pages/write-tweet/write-tweet.ts

@@ -1,379 +0,0 @@
-import { Component } from "@angular/core";
-import {
-  IonicPage,
-  NavController,
-  NavParams,
-  LoadingController,
-  AlertController
-} from "ionic-angular";
-import {
-  FormBuilder,
-  Validators,
-  FormGroup,
-  ValidatorFn,
-  AbstractControl
-} from "@angular/forms";
-import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";
-import { Storage } from "@ionic/storage";
-import { P2pStorageIpfsProvider } from "../../providers/p2p-storage-ipfs/p2p-storage-ipfs";
-import { P2pDatabaseGunProvider } from "../../providers/p2p-database-gun/p2p-database-gun";
-import twittertext from "twitter-text";
-import { CryptoProvider } from "../../providers/crypto/crypto";
-import * as openpgp from 'openpgp';
-
-@IonicPage()
-@Component({
-  selector: "page-write-tweet",
-  templateUrl: "write-tweet.html"
-})
-export class WriteTweetPage {
-  tweet: FormGroup;
-  retweetId: string;
-  replyToStatusId: string;
-  retweet;
-  replyTweet;
-  openpgp;
-  privateKey;
-  publicKey;
-  pk: any[]=[];
-  passp = 'super long and hard to guess secret';
-  hkp = new openpgp.HKP();
- 
-
-  constructor(
-    public navCtrl: NavController,
-    public navParams: NavParams,
-    private formBuilder: FormBuilder,
-    private twitter: TwitterApiProvider,
-    private loadingCtrl: LoadingController,
-    private storage: Storage,
-    private ipfs: P2pStorageIpfsProvider,
-    private gun: P2pDatabaseGunProvider,
-    private cryptoUtils: CryptoProvider,
-    private alertCtrl: AlertController
-  ) {
-    this.retweetId = this.navParams.get("tweetId");
-    this.replyToStatusId = this.navParams.get("replyToStatus");
-
-    this.tweet = this.formBuilder.group({
-      text: [""],
-      p2p: [false]
-    });
-
-    this.addValidators();
-    // this.encryptDecryptFunction();
-  }
-
-
-//    public async encryptDecryptFunction () {
-//      await openpgp.initWorker({path:'assets/scripts/openpgp.worker.js'});
-//     let a =  await this.generateKeys();
-//     console.log('a is:',a.publicKeyArmored);
-//     let b  =  await this.generateKeys();
-//     console.log('b is:',b.publicKeyArmored);
-//     let c  =  await this.generateKeys();
-//     this.privateKey =c.privateKeyArmored;
-//     this.publicKey = c.publicKeyArmored;
-
-//     this.pk.push(a.publicKeyArmored);
-//     this.pk.push(b.publicKeyArmored);
-// //     this.pk = [`----BEGIN PGP PUBLIC KEY BLOCK-----
-// // Version: OpenPGP.js v4.7.1
-// // Comment: https://openpgpjs.org
-
-// // xjMEXfAn1xYJKwYBBAHaRw8BAQdAAMVNOABw8MBtrtYR8KC3tSro3wITyApT
-// // TVjKVCppD+DNG0pvbiBTbWl0aCA8am9uQGV4YW1wbGUuY29tPsJ3BBAWCgAf
-// // BQJd8CfXBgsJBwgDAgQVCAoCAxYCAQIZAQIbAwIeAQAKCRD+efBRXzuMsfA7
-// // AQCEgoToFzv2hT9BREdiQp531/AHSyoZWmWvSZSvmga40gD8C+zwbCySnkhQ
-// // pb4L0DCKtSDa7pLg2g0OcxJlbSZWHQ3OOARd8CfXEgorBgEEAZdVAQUBAQdA
-// // p4mVY17dPWf6VCBqW10Ybk5JgUO6FK0OsETWw3gG2zcDAQgHwmEEGBYIAAkF
-// // Al3wJ9cCGwwACgkQ/nnwUV87jLFHbAD9GyoL7dcTDGQoqtrhKozdgnzfugTb
-// // er0bwU15WNMjefkA/jEqK9YUNcRrFKIuac9PVibGgutL8ak7ukysw6iTcCsM
-// // =fmhE
-// // -----END PGP PUBLIC KEY BLOCK-----`,
-// // `-----BEGIN PGP PUBLIC KEY BLOCK-----
-// // Version: OpenPGP.js v4.7.1
-// // Comment: https://openpgpjs.org
-
-// // xjMEXfAn1hYJKwYBBAHaRw8BAQdAsF1ivpd0HU8ogj02LDv6BTOxNMWGZaEc
-// // OyZBwqoYJPrNG0pvbiBTbWl0aCA8am9uQGV4YW1wbGUuY29tPsJ3BBAWCgAf
-// // BQJd8CfWBgsJBwgDAgQVCAoCAxYCAQIZAQIbAwIeAQAKCRDEruv77flRJ32B
-// // AP93GIBcUW2okROoZZhdPVeqjRD72Ft64imXpdZ0jx4ohgEA5Kv9vs2kV73q
-// // k6fcdf7qD/i5gMExU0+vV05c9VxBYwfOOARd8CfWEgorBgEEAZdVAQUBAQdA
-// // 1J7E03ZopUnsIeNzeiZvba6qxhhUbpmBZ1aN1HhWUlEDAQgHwmEEGBYIAAkF
-// // Al3wJ9YCGwwACgkQxK7r++35USdTqQD/ZEg8X5tMx75nQe4mGlyiRjmmtWLw
-// // n9bslTdjBIszs/EA/R1WIm6ji4Ru1dJWc3ISisz78xTM2H8U7fnP8yjFcWcD
-// // =hgnW
-// // -----END PGP PUBLIC KEY BLOCK-----`];
-//     console.log('array of pub keys is :',this.pk);
-//      this.pk = this.pk.map(async (key) => {
-//       return (await openpgp.key.readArmored(key)).keys[0]
-//     });
-
-//     console.log('priv key: ',this.privateKey,'this.pubkey',this.pk);
-//     let encrypted;
-//     const privKeyObj = (await openpgp.key.readArmored(this.privateKey)).keys[0];
-//     console.log('privKeyObj',privKeyObj);
-//     const bla = await privKeyObj.decrypt(this.passp);
-
-//     // const options = {
-//     //     message: openpgp.message.fromText('Hello, World!'),       // input as Message object
-//     //     publicKeys: (await openpgp.key.readArmored(this.publicKey)).keys, // for encryption
-//     //     privateKeys: [privKeyObj]                                 // for signing (optional)
-//     // }
-
-//     const options = {
-//         message: openpgp.message.fromText('Hello, World!'),       // input as Message object
-//         publicKeys: await Promise.all(this.pk), // for encryption
-//         privateKeys: [privKeyObj]                                 // for signing (optional)
-//     }
-
-//     const ciphertext = await openpgp.encrypt(options);
-//       encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
-//         console.log('encrypted is:',encrypted);
-   
-//    let aprivKeyObj = (await openpgp.key.readArmored(a.privateKeyArmored)).keys[0];
-//    await aprivKeyObj.decrypt(this.passp);
-
-//     const options2 = {
-//         message: await openpgp.message.readArmored(encrypted),    // parse armored message
-//         privateKeys: [aprivKeyObj]                                 // for decryption
-//     }
-//     console.log('options2 is: ',options2);
-//     let plaintext = await openpgp.decrypt(options2);
-//     console.log('decrypted text is:',plaintext,plaintext.data);
-//     return plaintext.data // 'Hello, World!'
-
-//   }
-
-  // public async generateKeys(){
-  //   let options = {
-  //     userIds: [{ name:'Jon Smith', email:'jon@example.com' }], // multiple user IDs
-  //     curve: "ed25519",                                         // ECC curve name
-  //     passphrase: this.passp        // protects the private key
-  //   };
-   
-  //    let a = await openpgp.generateKey(options);
-  //    return a;
-  //     // console.log('resolved a = ',a);
-  //     //     this.privateKey =a.privateKeyArmored;
-  //     //     this.publicKey = a.publicKeyArmored;
-  //     //     this.encryptDecryptFunction();
-  // }
-
-
-  private async addValidators() {
-    const triggerWords = await this.storage.get("keywords");
-    const validators = [
-      Validators.maxLength(140),
-      this.containsTriggerWord(triggerWords)
-    ];
-    this.tweet.controls["text"].setValidators(validators);
-  }
-
-  private containsTriggerWord(triggerWords: string): ValidatorFn {
-    return (control: AbstractControl): { [key: string]: any } | null => {
-      if (triggerWords) {
-        const regexList = triggerWords
-          .toLowerCase()
-          .split(", ")
-          .join("|");
-        const regex = new RegExp(regexList);
-        const containsTriggerWord = regex.test(control.value.toLowerCase());
-        return containsTriggerWord
-          ? { containsTriggerWord: { value: control.value } }
-          : null;
-      } else {
-        return null;
-      }
-    };
-  }
-
-  async ionViewDidLoad() {
-    if (this.retweetId) {
-      this.retweet = await this.twitter.fetchTweet(this.retweetId);
-    }
-    if (this.replyToStatusId) {
-      this.replyTweet = await this.twitter.fetchTweet(this.replyToStatusId);
-    }
-  }
-
-  get tweetCharProgress() {
-    const progress = 1 - this.tweet.value["text"].length / 140;
-    const radius = 8;
-    const circumference = Math.PI * radius * 2;
-    return progress * circumference;
-  }
-
-  get showTrigger(): boolean {
-    return (
-      this.tweet &&
-      this.tweet.controls &&
-      this.tweet.controls.text &&
-      this.tweet.controls.text.errors &&
-      this.tweet.controls.text.errors["containsTriggerWord"] &&
-      !this.tweet.controls.p2p.value
-    );
-  }
-
-  showTriggerInfo() {
-    this.alertCtrl
-      .create({
-        title: "Watch Out!",
-        message:
-          "Your tweet contains words you have previously defined to only share securely via P2P. Currently P2P mode is not selected.",
-        buttons: ["OK"]
-      })
-      .present();
-  }
-
-  async submitTweet() {
-    console.log('Submitting tweet')
-    const loading = this.loadingCtrl.create();
-    loading.present();
-
-    if (this.tweet.value.p2p) {
-      loading.setContent("Validate keys...");
-      if (
-        (await this.cryptoUtils.isPrivateKeySet()) &&
-        (await this.cryptoUtils.isPublicKeyPublished())
-      ) {
-        loading.setContent("Publish private tweet...");
-        await this.tweetPrivate();
-        } else {
-        loading.dismiss();
-        const alert = this.alertCtrl.create({
-          title: "Oooops...",
-          message:
-            "Please verify that you have set a private and public key in the settings and that your latest public key was published."
-        });
-        alert.present();
-        return;
-      }
-    } else {
-      loading.setContent("Publish on Twitter...");
-      await this.twitter.tweet(
-        this.tweet.value["text"],
-        this.retweet,
-        this.replyToStatusId
-      );
-    }
-
-    loading.dismiss();
-    this.navCtrl.pop();
-  }
-
-   public async lookupKeys(email:string){
-     var options = {
-        query: email
-    };
-
-    let armoredPubkey = await this.hkp.lookup(options);
-    console.log('armord pubkey',armoredPubkey);
-
-    let pubkey = (await openpgp.key.readArmored(armoredPubkey));
-    // console.log('array of opubkes returened from server',pubkey);
-
-     pubkey = (await openpgp.key.readArmored(armoredPubkey)).keys[0];
-    // console.log('latest  pubkey is:',pubkey);
-     // console.log('Found public key:',pubkey);
-    
-    this.pk.push(pubkey);
-
-  }
-
-  private async tweetPrivate() {
-    const tweet = await this.buildPrivateTweet();
-    console.log('tweet is:',tweet.full_text);
-    const privateKey = await this.storage.get("privateKey");
-    //fetch followers and their public keys
-    //assuming the email id of rohit.shiva.gowda
-    await this.lookupKeys('rohit.hosn@gmail.com');
-
-
-     console.log('array of pub keys is :', this.pk);
-    this.pk = this.pk.map(async (key) => {
-      console.log('key is:',key);
-      return (await openpgp.key.readArmored(key)).keys[0]
-    });
-
-    console.log("after mapping", this.pk);
-
-    const options = {
-      message: openpgp.message.fromText(tweet), // input as Message object
-      publicKeys: await Promise.all(this.pk), // for encryption
-      // privateKeys: [privKeyObj] // for signing (optional)
-    }
-
-    const ciphertext = await openpgp.encrypt(options);
-
-    const encryptedTweet = ciphertext.data;
-    console.log('encrypted tweet is:',encryptedTweet);
-
-    // const encryptedTweet = this.cryptoUtils.encrypt(
-    //   JSON.stringify(tweet),
-    //   privateKey
-    // );
-    const res = await this.ipfs.storeTweet(encryptedTweet);
-
-    this.gun.storeLastTweetHashForUser(
-      tweet.user_id,
-      res["Hash"],
-      tweet.created_at
-    );
-
-    this.gun.publishHashtags(tweet.entities.hashtags);
-  }
-
-  private async buildPrivateTweet() {
-    const status = this.tweet.value["text"].trim();
-    const entities = await this.getEntities(status);
-
-    return {
-      full_text: status,
-      user_id: await this.storage.get("userId"),
-      created_at: Date.now(),
-      private_tweet: true,
-      in_reply_to_status_id: this.replyToStatusId,
-      quoted_status_id: this.retweetId,
-      display_text_range: [0, status.length],
-      entities: entities
-    };
-  }
-
-  private async getEntities(status: string) {
-    return {
-      hashtags: twittertext.extractHashtagsWithIndices(status),
-      urls: twittertext.extractUrlsWithIndices(status),
-      user_mentions: await this.getMentions(status)
-    };
-  }
-
-  private async getMentions(status: string) {
-    // extract mentions
-    const entities = twittertext.extractMentionsWithIndices(status);
-
-    // add user_id
-    const entitiesWithPromises = entities.map(async mention => {
-      try {
-        const user = await this.twitter.fetchUserFromScreenName(
-          mention.screenName
-        );
-        mention["id_str"] = user[0]["id_str"];
-        mention["screen_name"] = mention.screenName;
-        delete mention.screenName;
-      } catch (err) {
-        console.error(
-          "There is no user signed up to twitter with username: " +
-            mention.screenName
-        );
-      }
-      return mention;
-    });
-
-    // filter for valid users and return
-    return (await Promise.all(entitiesWithPromises)).filter(el =>
-      el.hasOwnProperty("id_str")
-    );
-  }
-}

+ 0 - 18
src1/pipes/diff-for-humans/diff-for-humans.ts

@@ -1,18 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import TimeAgo from "javascript-time-ago";
-import en from "javascript-time-ago/locale/en";
-
-TimeAgo.locale(en);
-const timeAgo = new TimeAgo("en-US");
-
-@Pipe({
-  name: "diffForHumans"
-})
-export class DiffForHumansPipe implements PipeTransform {
-  /**
-   * Takes a timestamp and makes the diff readable for humans.
-   */
-  transform(value: string, ...args) {
-    return timeAgo.format(new Date(value), "twitter");
-  }
-}

+ 0 - 19
src1/pipes/friendly-number/friendly-number.ts

@@ -1,19 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-
-@Pipe({
-  name: "friendlyNumber"
-})
-export class FriendlyNumberPipe implements PipeTransform {
-  /**
-   * Takes a number and formats it using binary prefixes
-   */
-  transform(value: number, ...args) {
-    if (value > 1000000) {
-      return (value / 1000000).toFixed(1) + "M";
-    } else if (value > 1000) {
-      return (value / 1000).toFixed(1) + "k";
-    } else {
-      return value;
-    }
-  }
-}

+ 0 - 15
src1/pipes/high-resolution/high-resolution.ts

@@ -1,15 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-
-@Pipe({
-  name: "highResolution"
-})
-export class HighResolutionPipe implements PipeTransform {
-  /**
-   * Takes a profile img URL string and removes "normal" from the URL to receive a high resolution image
-   */
-  transform(value: string, ...args) {
-    if (value) {
-      return value.replace("_normal", "_400x400");
-    }
-  }
-}

+ 0 - 24
src1/pipes/pipes.module.ts

@@ -1,24 +0,0 @@
-import { NgModule } from "@angular/core";
-import { FriendlyNumberPipe } from "./friendly-number/friendly-number";
-import { DiffForHumansPipe } from "./diff-for-humans/diff-for-humans";
-import { ReplaceUrlsPipe } from "./replace-urls/replace-urls";
-import { ReplaceHashtagsPipe } from "./replace-hashtags/replace-hashtags";
-import { HighResolutionPipe } from './high-resolution/high-resolution';
-@NgModule({
-  declarations: [
-    FriendlyNumberPipe,
-    DiffForHumansPipe,
-    ReplaceUrlsPipe,
-    ReplaceHashtagsPipe,
-    HighResolutionPipe
-  ],
-  imports: [],
-  exports: [
-    FriendlyNumberPipe,
-    DiffForHumansPipe,
-    ReplaceUrlsPipe,
-    ReplaceHashtagsPipe,
-    HighResolutionPipe
-  ]
-})
-export class PipesModule {}

+ 0 - 20
src1/pipes/replace-hashtags/replace-hashtags.ts

@@ -1,20 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-
-@Pipe({
-  name: "replaceHashtags"
-})
-export class ReplaceHashtagsPipe implements PipeTransform {
-  /**
-   * Takes a string and highlights the hashtags.
-   */
-  transform(value: string, ...args) {
-    for (let hashtag of args[0]) {
-      value = value.replace(
-        "#" + hashtag.text,
-        '<span class="hashtag">#' + hashtag.text + "</span>"
-      );
-    }
-
-    return value;
-  }
-}

+ 0 - 24
src1/pipes/replace-urls/replace-urls.ts

@@ -1,24 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-
-@Pipe({
-  name: "replaceUrls"
-})
-export class ReplaceUrlsPipe implements PipeTransform {
-  /**
-   * Takes a string and replaces the urls with hyperlinks.
-   */
-  transform(value: string, ...args) {
-    for (let url of args[0]) {
-      value = value.replace(
-        url["url"],
-        '<a href="' +
-          url["expanded_url"] +
-          '" target="_blank">' +
-          url["display_url"] +
-          "</a>"
-      );
-    }
-
-    return value;
-  }
-}

+ 0 - 72
src1/providers/auth/auth.ts

@@ -1,72 +0,0 @@
-import { HttpClient } from "@angular/common/http";
-import { Injectable } from "@angular/core";
-import { Storage } from "@ionic/storage";
-import firebase from "firebase";
-import { TwitterApiProvider } from "../twitter-api/twitter-api";
-
-@Injectable()
-export class AuthProvider {
-  authProvider: any;
-
-  constructor(
-    public http: HttpClient,
-    private storage: Storage,
-    private twitter: TwitterApiProvider
-  ) {
-    const config = {
-      apiKey: "AIzaSyCMYjjtPPZak7wBBnh9sy8Yr3Fz1145MuM",
-      authDomain: "hybridosn.firebaseapp.com",
-      databaseURL: "https://hybridosn.firebaseio.com",
-      storageBucket: "hybridosn.appspot.com"
-    };
-    firebase.initializeApp(config);
-
-    this.authProvider = new firebase.auth.TwitterAuthProvider();
-    this.authProvider.setCustomParameters({
-      lang: "de"
-    });
-  }
-
-  /**
-   * Performs the login to Twitter
-   */
-  login() {
-    return firebase
-      .auth()
-      .signInWithRedirect(this.authProvider)
-      .then(() => firebase.auth().getRedirectResult())
-      .then(this.setKeys)
-      .then(() => this.twitter.initApi());
-  }
-
-  /**
-   * Logs the user out by deleting session data
-   */
-  logout() {
-    this.storage.clear();
-  }
-
-  /**
-   * Checks if a user is currently logged in
-   */
-  async isLoggedIn() {
-    let accessToken = await this.storage.get("accessTokenKey");
-    let accessTokenKey = await this.storage.get("accessTokenSecret");
-    return accessToken && accessTokenKey;
-  }
-
-  /**
-   * Saves acces token and user id to locale storage
-   */
-  setKeys = async result => {
-    await this.storage.set(
-      "accessTokenKey",
-      result["credential"]["accessToken"]
-    );
-    await this.storage.set("accessTokenSecret", result["credential"]["secret"]);
-    await this.storage.set(
-      "userId",
-      result["additionalUserInfo"]["profile"]["id_str"]
-    );
-  };
-}

+ 0 - 347
src1/providers/crypto/crypto.ts

@@ -1,347 +0,0 @@
-import { Injectable } from "@angular/core";
-import { TwitterApiProvider } from "../twitter-api/twitter-api";
-import { P2pStorageIpfsProvider } from "../p2p-storage-ipfs/p2p-storage-ipfs";
-import { Storage } from "@ionic/storage";
-import NodeRSA from "node-rsa";
-import * as openpgp from 'openpgp';
-declare var TextDecoder: any;
-declare var TextEncoder: any;
-@Injectable()
-export class CryptoProvider {
-  ownUserId: string;
-  IV_LENGTH = 12;
-  HYBRID_OSN_AES_KEY = "Z1vxAULQnZdoWhJOvv+hWEvVpyUHzNjD/ichEE2c8i4=";
-
-  constructor(
-    private twitter: TwitterApiProvider,
-    private ipfs: P2pStorageIpfsProvider,
-    private storage: Storage
-  ) {
-    this.init();
-  }
-
-  private async init() {
-    this.ownUserId = await this.storage.get("userId");
-  }
-
-  /**
-   * Publishs the public key history with the latest key
-   * @param key key to publish
-   */
-  public async publishPublicKey(key: string) {
-    let publicKeyHistory = await this.getKeyHistory(this.ownUserId);
-
-    // Todo: avoid publishing the same public key twice - check if new key equals newest key in history
-
-    // Add new key to history
-    const newKey = {
-      key: key,
-      validFrom: Date.now()
-    };
-
-    if (publicKeyHistory) {
-      publicKeyHistory["keys"].push(newKey);
-    } else {
-      publicKeyHistory = {
-        keys: [newKey]
-      };
-    }
-
-    // Ecnrypt key history
-    const encryptedPublicKeyHistory = await this.aesEncrypt(
-      JSON.stringify(publicKeyHistory)
-    );
-
-    // Publish updated key history...
-    const res = await this.ipfs.storePublicKey(encryptedPublicKeyHistory);
-
-    // tweet ipfs link
-    const tweetResponse = await this.twitter.tweet(
-      "ipfs://" + res["Hash"] + " #hybridOSN"
-    );
-
-    // ... and update description in user profile with tweet id
-    this.twitter.updateProfileDescription(
-      "tweet://" + tweetResponse["data"]["id_str"] + " #hybridOSN"
-    );
-  }
-
-  private async getKeyHistory(userId: string) {
-    // Get user description
-    const userData = await this.twitter.fetchUser(userId);
-    const profileDescription = userData["description"];
-
-    // Get tweet with link to key history
-    const tweetId = this.extractTweetId(profileDescription);
-    if (tweetId.length === 0) {
-      return null;
-    }
-    const tweetWithKeyHistoryLink = await this.twitter.fetchTweet(tweetId);
-
-    // Extract link to public key
-    const link = this.extractLinkFromDescription(
-      tweetWithKeyHistoryLink["data"]["full_text"]
-    );
-
-    // Fetch public key history
-    if (link.length) {
-      const encryptedKeyHistory = await this.ipfs.fetchJson(link);
-      // Decrypt key history
-      const keyHistory = await this.aesDecrypt(encryptedKeyHistory.toString());
-      return JSON.parse(keyHistory);
-    } else {
-      return null;
-    }
-  }
-
-  private extractTweetId(text: string): string {
-    for (let word of text.split(" ")) {
-      if (this.isTweetId(word)) {
-        return word.substr(8);
-      }
-    }
-    return "";
-  }
-
-  private extractLinkFromDescription(text: string): string {
-    for (let word of text.split(" ")) {
-      if (this.isIpfsLink(word)) {
-        return word.substr(7);
-      }
-    }
-    return "";
-  }
-
-  private isIpfsLink(word: string): boolean {
-    return /ipfs:\/\/Qm[a-zA-Z0-9]+/.test(word);
-  }
-
-  private isTweetId(word: string): boolean {
-    return /tweet:\/\/[0-9]+/.test(word);
-  }
-
-  /**
-   * Generates a RSA key pair object
-   */
-  public async generateRsaKeys() {
-    return await crypto.subtle.generateKey(
-      {
-        name: "RSA-OAEP",
-        modulusLength: 1024,
-        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
-        hash: { name: "SHA-256" }
-      },
-      true,
-      ["encrypt", "decrypt"]
-    );
-  }
-
-  public async generatePgpKeys(email){
-    console.log("this is the mail of the iser ", email);
-    let options = {
-      userIds: [{ name: 'Rohithosn', email:email }], // multiple user IDs
-      curve: "ed25519",                                         // ECC curve name
-      passphrase: "This is phas"        // protects the private key
-    };
-   
-     let a = await openpgp.generateKey(options);
-     console.log('resolved a = ',a);
-     return a;
-      
-      //     this.privateKey =a.privateKeyArmored;
-      //     this.publicKey = a.publicKeyArmored;
-      //     this.encryptDecryptFunction();
-  }
-
-  /**
-   * extracts the private key from the key object and transforms it to readable text
-   * @param keys key object
-   */
-  public async extractPrivateKey(keys): Promise<string> {
-    return btoa(
-      String.fromCharCode.apply(
-        null,
-        new Uint8Array(await crypto.subtle.exportKey("pkcs8", keys.privateKey))
-      )
-    );
-  }
-
-  /**
-   * extracts the public key from the key object and transforms it to readable text
-   * @param keys key object
-   */
-  public async extractPublicKey(keys): Promise<string> {
-    return btoa(
-      String.fromCharCode.apply(
-        null,
-        new Uint8Array(await crypto.subtle.exportKey("spki", keys.publicKey))
-      )
-    );
-  }
-
-  /**
-   * checks if the latest published key is the same as the one saved in app settings
-   */
-  public async isPublicKeyPublished(): Promise<boolean> {
-    const publicKey = await this.storage.get("publicKey");
-    return publicKey;
-    // const keyHistory = await this.getKeyHistory(this.ownUserId);
-
-    // if (keyHistory && publicKey.length) {
-    //   const newestPublicKey = keyHistory["keys"].reverse()[0]["key"];
-    //   return newestPublicKey === publicKey;
-    // } else {
-    //   return false;
-    // }
-  }
-
-  /**
-   * checks if a private key is already set
-   */
-  public async isPrivateKeySet(): Promise<boolean> {
-    const privateKey = await this.storage.get("privateKey");
-    return privateKey;
-  }
-
-  /**
-   * Encrypt text with RSA
-   * @param plainText plain text
-   * @param privateKey private key
-   */
-  public encrypt(plainText: string, privateKey: string) {
-    const key = new NodeRSA(
-      `-----BEGIN PRIVATE KEY-----${privateKey}-----END PRIVATE KEY-----`
-    );
-    return key.encryptPrivate(plainText, "base64");
-  }
-
-  /**
-   * Decrypt secret with RSA
-   * @param encryptedMessage encrypted message
-   * @param publicKey public key
-   */
-  public decrypt(encryptedMessage: string, publicKey: string): string {
-    const key = new NodeRSA(
-      `-----BEGIN PUBLIC KEY-----${publicKey}-----END PUBLIC KEY-----`
-    );
-    return key.decryptPublic(encryptedMessage).toString();
-  }
-
-  /**
-   * Fetches the public key history for a given user id
-   * @param userId user id
-   */
-  public async fetchPublicKeyHistoryForUser(userId: string): Promise<object[]> {
-    const keyHistory = await this.getKeyHistory(userId);
-    return keyHistory["keys"].reverse();
-  }
-
-  private async aesEncrypt(plainText: string) {
-    const utf8BytesOfPlainText = new TextEncoder().encode(plainText);
-
-    const iv = crypto.getRandomValues(new Uint8Array(this.IV_LENGTH));
-    const keyBytes = this.base64ToBytes(this.HYBRID_OSN_AES_KEY);
-
-    const algorithm = { name: "AES-GCM", iv, length: 256 };
-
-    return crypto.subtle
-      .importKey("raw", keyBytes, algorithm, false, ["encrypt"])
-      .then((cryptoKey: CryptoKey) => {
-        return crypto.subtle.encrypt(
-          algorithm,
-          cryptoKey,
-          utf8BytesOfPlainText
-        );
-      })
-      .then((encData: ArrayBuffer) =>
-        this.mergeBytes(iv, this.bufferToBytes(encData))
-      )
-      .then(this.bytesToBase64);
-  }
-
-  private aesDecrypt(encryptedMessage: string) {
-    try {
-      const ivWithEncryptedBytes = this.base64ToBytes(encryptedMessage);
-
-      const { encryptedBytes, ivBytes } = this.splitIvAndEncrypted(
-        ivWithEncryptedBytes
-      );
-
-      const keyBytes = this.base64ToBytes(this.HYBRID_OSN_AES_KEY);
-
-      const algorithm = { name: "AES-GCM", iv: ivBytes, length: 256 };
-
-      return crypto.subtle
-        .importKey("raw", keyBytes, algorithm, false, ["decrypt"])
-        .then((cryptoKey: CryptoKey) => {
-          return crypto.subtle.decrypt(algorithm, cryptoKey, encryptedBytes);
-        })
-        .then((decryptedData: ArrayBuffer) => {
-          return new TextDecoder().decode(decryptedData);
-        });
-    } catch (e) {
-      return Promise.reject(e);
-    }
-  }
-
-  private bufferToBytes(arrayBuffer: ArrayBuffer) {
-    return new Uint8Array(arrayBuffer);
-  }
-
-  private bytesToBase64(bytes: Uint8Array): string {
-    let binary = "";
-
-    const len = bytes.length;
-    for (let i = 0; i < len; i++) {
-      binary += String.fromCharCode(bytes[i]);
-    }
-
-    return btoa(binary);
-  }
-
-  private base64ToBytes(base64: string): Uint8Array {
-    const binaryString = atob(base64);
-
-    const len = binaryString.length;
-    const bytes = new Uint8Array(len);
-    for (let i = 0; i < len; i++) {
-      bytes[i] = binaryString.charCodeAt(i);
-    }
-
-    return bytes;
-  }
-
-  private mergeBytes(a: Uint8Array, b: Uint8Array) {
-    const aLen = a.length;
-    const bLen = b.length;
-
-    const res = new Uint8Array(aLen + bLen);
-
-    for (let i = 0; i < aLen; i++) {
-      res[i] = a[i];
-    }
-
-    for (let i = 0; i < bLen; i++) {
-      res[i + aLen] = b[i];
-    }
-
-    return res;
-  }
-
-  private splitIvAndEncrypted(ivWithEncryptedBytes: Uint8Array) {
-    const dataLen = ivWithEncryptedBytes.length;
-
-    const ivBytes = new Uint8Array(this.IV_LENGTH);
-    const encryptedBytes = new Uint8Array(dataLen - this.IV_LENGTH);
-
-    for (let i = 0; i < this.IV_LENGTH; i++) {
-      ivBytes[i] = ivWithEncryptedBytes[i];
-    }
-
-    for (let i = this.IV_LENGTH; i < dataLen; i++) {
-      encryptedBytes[i - this.IV_LENGTH] = ivWithEncryptedBytes[i];
-    }
-
-    return { ivBytes, encryptedBytes };
-  }
-}

+ 0 - 229
src1/providers/feed/feed.ts

@@ -1,229 +0,0 @@
-import { Injectable } from "@angular/core";
-import { TwitterApiProvider } from "../twitter-api/twitter-api";
-import { P2pDatabaseGunProvider } from "../p2p-database-gun/p2p-database-gun";
-import { P2pStorageIpfsProvider } from "../p2p-storage-ipfs/p2p-storage-ipfs";
-import { CryptoProvider } from "../crypto/crypto";
-import { Storage } from "@ionic/storage";
-@Injectable()
-export class FeedProvider {
-  friends;
-  userId: string;
-
-  constructor(
-    private twitter: TwitterApiProvider,
-    private gun: P2pDatabaseGunProvider,
-    private ipfs: P2pStorageIpfsProvider,
-    private cryptoUtils: CryptoProvider,
-    private storage: Storage
-  ) {
-    this.storage.get("userId").then(userId => (this.userId = userId));
-  }
-
-  /**
-   * Retrives the public and private tweets for a user
-   * Since it is loaded in batches of 20 public tweets, public and private tweet are used as reference to load next 20 tweets
-   * @param userId user id
-   * @param oldestPublicTweet oldest public tweet
-   * @param oldestPrivateTweet oldest private tweet
-   */
-  public async loadUserTimeline(
-    userId,
-    oldestPublicTweet?,
-    oldestPrivateTweet?
-  ) {
-    const maxId = oldestPublicTweet ? oldestPublicTweet["id_str"] : undefined;
-    // Fetch tweets from Twitter
-    let tweets = await this.twitter.fetchUserTimeline(userId, maxId);
-    if (tweets.length === 0) return tweets;
-    tweets = tweets.filter(tweet => tweet.id_str != maxId);
-
-    // Determine start and end of time interval to look for private tweets
-    const intervalStart: Date = oldestPrivateTweet
-      ? new Date(oldestPrivateTweet["created_at"])
-      : new Date();
-    const intervalEnd: Date = this.getOldestTweetTimestamp(tweets);
-
-    // Fetch private tweet hashs from P2P DB for corresponding interval
-    const privateTweetHashs: object[] = await this.gun.fetchPrivateTweetHashsForUserInInterval(
-      userId,
-      intervalStart,
-      intervalEnd
-    );
-
-    if (privateTweetHashs.length > 0) {
-      const privateTweets = await this.fetchPrivateTweets(privateTweetHashs);
-
-      // Combine and sort tweets
-      return tweets
-        .concat(privateTweets)
-        .sort((a, b) => this.sortByDateAsc(a, b));
-    } else {
-      return tweets;
-    }
-  }
-
-  /**
-   * Retrieves the home feed for the logged in user
-   * Since it is loaded in batches of 20 public tweets, public and private tweet are used as reference to load next 20 tweets
-   * @param oldestPublicTweet oldest public tweet
-   * @param oldestPrivateTweet oldest private tweet
-   */
-  public async loadHomeTimeline(oldestPublicTweet?, oldestPrivateTweet?) {
-    // Fetch tweets from Twitter
-    const maxId = oldestPublicTweet ? oldestPublicTweet["id_str"] : undefined;
-    let tweets = await this.twitter.fetchHomeFeed(maxId);
-    tweets = tweets.filter(tweet => tweet.id_str != maxId);
-
-    // Determine start and end of time interval to look for private tweets
-    const intervalStart: Date = oldestPrivateTweet
-      ? new Date(oldestPrivateTweet["created_at"])
-      : new Date();
-    const intervalEnd: Date = this.getOldestTweetTimestamp(tweets);
-
-    // Fetch user's friends
-    const friends = await this.getCachedFriends(this.userId);
-
-    // Extract friends user ids and add own user id
-    const friendsAndUserIds = friends
-      .map(friend => friend.id_str)
-      .concat([this.userId]);
-
-    // Fetch ipfs hashs for period
-    const promises: Promise<object[]>[] = friendsAndUserIds.map(accountId => {
-      return this.gun.fetchPrivateTweetHashsForUserInInterval(
-        accountId,
-        intervalStart,
-        intervalEnd
-      );
-    });
-
-    const resolvedPromises = await Promise.all(promises);
-    const privateTweetHashs = resolvedPromises.reduce(
-      (privateTweets, el) => privateTweets.concat(el),
-      []
-    );
-
-    if (privateTweetHashs.length > 0) {
-      const privateTweets = await this.fetchPrivateTweets(privateTweetHashs);
-
-      // Combine and sort tweets
-      return tweets
-        .concat(privateTweets)
-        .sort((a, b) => this.sortByDateAsc(a, b));
-    } else {
-      return tweets;
-    }
-  }
-
-  private async fetchPrivateTweets(privateTweetsData: object[]) {
-    const privateTweets = [];
-
-    // Load private tweets from P2P storage
-    for (let i = 0; i < privateTweetsData.length; i++) {
-      const hash = privateTweetsData[i]["hash"];
-      const userId = privateTweetsData[i]["userId"];
-      const timestamp = privateTweetsData[i]["created_at"];
-
-      // fetch from IPFS
-      const encryptedTweet = await this.ipfs.fetchTweet(hash);
-
-      // Fetch public key history for user
-      const publicKeyHistory: object[] = await this.cryptoUtils.fetchPublicKeyHistoryForUser(
-        userId
-      );
-
-      // Decrypt tweets
-      const decryptedTweet = this.cryptoUtils.decrypt(
-        encryptedTweet,
-        this.getPublicKeyAt(timestamp, publicKeyHistory)
-      );
-      privateTweets.push(JSON.parse(decryptedTweet));
-    }
-
-    // Add retweeted/quoted status
-    privateTweets.map(async tweet => await this.addQuotedStatusToTweet(tweet));
-
-    // Add original status (reply to)
-    privateTweets.map(
-      async tweet => await this.addOriginalStatusToTweet(tweet)
-    );
-
-    // Add user object to private tweets
-    return await Promise.all(
-      privateTweets.map(async tweet => await this.addUserToTweet(tweet))
-    );
-  }
-
-  private getPublicKeyAt(
-    timestamp: string,
-    publicKeyHistory: object[]
-  ): string {
-    const timestampTweet = new Date(timestamp).getTime();
-    for (let key of publicKeyHistory) {
-      const timestampKey = new Date(key["validFrom"]).getTime();
-      if (timestampTweet > timestampKey) {
-        return key["key"];
-      }
-    }
-    // todo: throw error
-    return "";
-  }
-
-  private async addUserToTweet(tweet: object): Promise<object> {
-    tweet["user"] = await this.twitter.fetchUser(tweet["user_id"]);
-    return tweet;
-  }
-
-  private async addQuotedStatusToTweet(tweet: object): Promise<object> {
-    if (!tweet["quoted_status_id"]) return tweet;
-    const quoted_status = await this.twitter.fetchTweet(
-      tweet["quoted_status_id"]
-    );
-    tweet["quoted_status"] = quoted_status["data"];
-    return tweet;
-  }
-
-  private async addOriginalStatusToTweet(tweet: object): Promise<object> {
-    if (!tweet["in_reply_to_status_id"]) return tweet;
-    const originalTweet = await this.twitter.fetchTweet(
-      tweet["in_reply_to_status_id"]
-    );
-    tweet["in_reply_to_screen_name"] =
-      originalTweet["data"]["user"]["screen_name"];
-    return tweet;
-  }
-
-  private getOldestTweetTimestamp(tweets): Date {
-    if (tweets.length < 15) {
-      // End of timeline is reached - load all private tweets
-      return new Date("2018-04-01T00:00:00");
-    } else {
-      const lastTweetTimestamp = tweets[tweets.length - 1].created_at;
-      return new Date(lastTweetTimestamp);
-    }
-  }
-
-  private sortByDateAsc(a, b) {
-    const dateA = new Date(a.created_at);
-    const dateB = new Date(b.created_at);
-
-    if (dateA > dateB) {
-      return -1;
-    } else if (dateA < dateB) {
-      return 1;
-    } else {
-      return 0;
-    }
-  }
-
-  private async getCachedFriends(userId) {
-    // Cache friends for 15 minutes to avoid unnecessary  API calls
-    if (!this.friends || (Date.now() - this.friends.lastUpdate) / 900000 > 15) {
-      this.friends = {
-        friendList: await this.twitter.fetchFriends(userId),
-        lastUpdate: Date.now()
-      };
-    }
-    return this.friends.friendList;
-  }
-}

+ 0 - 130
src1/providers/p2p-database-gun/p2p-database-gun.ts

@@ -1,130 +0,0 @@
-import { Injectable } from "@angular/core";
-import Gun from "gun/gun";
-import "gun/lib/then";
-
-@Injectable()
-export class P2pDatabaseGunProvider {
-  private gun;
-  osnPrefix: string = "hybridOSN-v1.0.0";
-
-  constructor() {
-    this.gun = Gun(["https://hosn-twitter-app.herokuapp.com/gun"]);
-  }
-
-  /**
-   * Hashtags are stored without reference to the users to provide these information on an extra dashboard to twitter
-   * @param hashtagEntity extracted hashtags
-   */
-  public async publishHashtags(hashtagEntity): Promise<void> {
-    const timestamp = new Date().setHours(0, 0, 1, 0);
-    const hashtagsSeparated = hashtagEntity
-      .map(el => el.hashtag)
-      .sort()
-      .join("|");
-
-    const randomId = Math.floor(Math.random() * 10000000000);
-
-    const hashtags = this.gun
-      .get(randomId)
-      .put({ hashtags: hashtagsSeparated });
-
-    this.gun
-      .get(this.osnPrefix)
-      .get("hashtags")
-      .get(timestamp)
-      .set(hashtags);
-  }
-
-  /**
-   * Store the ipfs hash to a private tweet in GUN
-   * @param userId user id
-   * @param hash ipfs hash
-   * @param timestamp timestamp
-   */
-  public storeLastTweetHashForUser(userId, hash, timestamp): void {
-    const tweet = this.gun
-      .get(timestamp)
-      .put({ hash: hash, created_at: timestamp });
-
-    this.gun
-      .get(this.osnPrefix)
-      .get("tweets")
-      .get(userId)
-      .set(tweet);
-  }
-
-  /**
-   * Retrieves the ipfs hashes of private tweets for a user in the given time interval
-   * @param userId user id
-   * @param intervalStart interval start timestamp
-   * @param intervalEnd interval end timestamp
-   */
-  public async fetchPrivateTweetHashsForUserInInterval(
-    userId,
-    intervalStart,
-    intervalEnd
-  ): Promise<object[]> {
-    const privateTweets = await this.gun
-      .get(this.osnPrefix)
-      .get("tweets")
-      .get(userId)
-      .then();
-
-    if (privateTweets) {
-      const entries = await Promise.all(
-        Object.keys(privateTweets)
-          .filter(key => key !== "_")
-          .map(key => this.gun.get(key).then())
-      );
-
-      return entries
-        .filter(entry => {
-          const createdAtDate = new Date(entry["created_at"]);
-          return createdAtDate < intervalStart && createdAtDate >= intervalEnd;
-        })
-        .map(entry => {
-          entry.userId = userId;
-          return entry;
-        });
-    } else {
-      return [];
-    }
-  }
-
-  /**
-   * Adds a like to a tweet privately
-   * @param tweetId tweet id
-   */
-  public async addLike(tweetId: string) {
-    const likeEntry = await this.getLikes(tweetId);
-
-    const likes = this.gun.get(tweetId).put({
-      likes: likeEntry.likes + 1
-    });
-
-    this.gun
-      .get(this.osnPrefix)
-      .get("likes")
-      .set(likes);
-  }
-
-  /**
-   * Retrieves the private likes for a tweet
-   * @param tweetId tweet id
-   */
-  public async getLikes(tweetId: string) {
-    const likeEntry = await this.gun
-      .get(this.osnPrefix)
-      .get("likes")
-      .get(tweetId)
-      .then();
-
-    if (likeEntry === undefined) {
-      return {
-        likes: 0
-      };
-    } else {
-      return likeEntry;
-    }
-  }
-}

+ 0 - 64
src1/providers/p2p-storage-ipfs/p2p-storage-ipfs.ts

@@ -1,64 +0,0 @@
-import { HttpClient } from "@angular/common/http";
-import { Injectable } from "@angular/core";
-
-@Injectable()
-export class P2pStorageIpfsProvider {
-  private infuraUrl = "https://ipfs.infura.io:5001/api/v0/";
-
-  constructor(public http: HttpClient) {}
-
-  /**
-   * Store private tweet on ipfs
-   * @param tweet tweet object
-   */
-  public storeTweet(tweet) {
-    return this.storeOnIPFS(tweet);
-  }
-
-  /**
-   * Store public key history on ipfs
-   * @param publicKeyHistory public key history object
-   */
-  public storePublicKey(publicKeyHistory) {
-    return this.storeOnIPFS(publicKeyHistory);
-  }
-
-  private storeOnIPFS(json) {
-    const formData = new FormData();
-    formData.append("data", JSON.stringify(json));
-
-    return this.http.post(this.infuraUrl + "add", formData).toPromise();
-  }
-
-  /**
-   * fetch data from ipfs for hash
-   * @param hash address hash
-   */
-  public async fetchJson(hash: string) {
-    const options = {
-      params: { arg: hash }
-    };
-
-    return await this.http.get(this.infuraUrl + "cat", options).toPromise();
-  }
-
-  /**
-   * fetch tweet from ipfs for hash
-   * @param hash address hash
-   */
-  public fetchTweet(hash: string): Promise<string> {
-    const options = {
-      params: { arg: hash }
-    };
-
-    return this.http.get<string>(this.infuraUrl + "cat", options).toPromise();
-  }
-
-  /**
-   * fetch multiple tweets from ipfs
-   * @param hashs array of hashes
-   */
-  public async fetchTweets(hashs: string[]): Promise<string[]> {
-    return await Promise.all(hashs.map(hash => this.fetchTweet(hash)));
-  }
-}

+ 0 - 284
src1/providers/twitter-api/twitter-api.ts

@@ -1,284 +0,0 @@
-import { Injectable } from "@angular/core";
-import { HttpClient } from "@angular/common/http";
-import { Storage } from "@ionic/storage";
-import Twit from "twit";
-
-@Injectable()
-export class TwitterApiProvider {
-  client: Twit;
-
-  constructor(public http: HttpClient, private storage: Storage) {
-    this.initApi();
-  }
-
-  /**
-   * initialize Twitter API provider
-   */
-  public async initApi() {
-    const access_token_key = await this.storage.get("accessTokenKey");
-    const access_token_secret = await this.storage.get("accessTokenSecret");
-    if (access_token_key && access_token_secret) {
-      this.client = new Twit({
-        consumer_key: "UxZkbKotkr8Uc6seupnaZ1kDE",
-        consumer_secret: "fEAas8iugR60FOEXsFG0iajq6oyfIIXRBVMlTgWxBd1stWIKHq",
-        access_token: access_token_key,
-        access_token_secret: access_token_secret,
-        timeout_ms: 60 * 1000 // optional HTTP request timeout to apply to all requests.
-      });
-    } else {
-      console.error(
-        "Access Token Key and Secret not set. Creating Twit-client not possible."
-      );
-      console.info("This error can be ignored if no user is logged in.");
-    }
-  }
-
-  /**
-   * fetch home feed in batches of 20 tweets starting at maxId
-   * @param maxId tweet id
-   */
-  public async fetchHomeFeed(maxId?) {
-    const res = await this.client.get("statuses/home_timeline", {
-      count: 20,
-      include_entities: true,
-      tweet_mode: "extended",
-      max_id: maxId
-    });
-    return res.data;
-  }
-
-  /**
-   * fetch user object to given id
-   * @param userId user id
-   */
-  public async fetchUser(userId) {
-    const res = await this.client.get("users/show", { user_id: userId });
-    return res.data;
-  }
-
-  /**
-   * lookup user for screenname
-   */
-  public async fetchUserFromScreenName(screenName) {
-    const res = await this.client.get("users/lookup", {
-      screen_name: screenName
-    });
-    return res.data;
-  }
-
-  /**
-   * fetch user feed in batches of 20 tweets starting at maxId
-   * @param userId user id
-   * @param maxId max tweet id
-   */
-  public async fetchUserTimeline(userId, maxId?) {
-    try {
-      const res = await this.client.get("statuses/user_timeline", {
-        user_id: userId,
-        max_id: maxId,
-        include_entities: true,
-        tweet_mode: "extended",
-        count: 20
-      });
-      return res.data;
-    } catch (e) {
-      console.error(e);
-      return [];
-    }
-  }
-
-  /**
-   * Follow user
-   * @param userId user id
-   */
-  public async createFriendship(userId) {
-    return await this.client.post("friendships/create", { user_id: userId });
-  }
-
-  /**
-   * Unfollow user
-   * @param userId user id
-   */
-  public async destroyFriendship(userId) {
-    return await this.client.post("friendships/destroy", { user_id: userId });
-  }
-
-  /**
-   * Mute user
-   * @param userId user id
-   */
-  public async muteUser(userId) {
-    return await this.client.post("mutes/users/create", { user_id: userId });
-  }
-
-  /**
-   * Unmute user
-   * @param userId user id
-   */
-  public async unmuteUser(userId) {
-    return await this.client.post("mutes/users/destroy", { user_id: userId });
-  }
-
-  /**
-   * Block user
-   * @param userId user id
-   */
-  public async blockUser(userId) {
-    return await this.client.post("blocks/create", { user_id: userId });
-  }
-
-  /**
-   * Unblock user
-   * @param userId user id
-   */
-  public async unblockUser(userId) {
-    return await this.client.post("blocks/destroy", { user_id: userId });
-  }
-
-  /**
-   * Post tweet
-   * @param status tweet message
-   * @param retweet tweet object to retweet
-   * @param replyToStatusId tweet id to reply to
-   */
-  public async tweet(status, retweet?, replyToStatusId?) {
-    if (status.length === 0 && retweet) {
-      // Simple retweet
-      return await this.client.post("statuses/retweet", {
-        id: retweet.data.id_str
-      });
-    } else if (!retweet) {
-      // Simple tweet
-      return await this.client.post("statuses/update", {
-        status: status,
-        in_reply_to_status_id: replyToStatusId
-      });
-    } else if (status.length > 0 && retweet) {
-      // Quoted tweet
-      const url =
-        "https://twitter.com/" +
-        retweet.data.user.screen_name +
-        "/status/" +
-        retweet.data.id_str;
-      return await this.client.post("statuses/update", {
-        status: status,
-        attachment_url: url
-      });
-    } else {
-      return;
-    }
-  }
-
-  /**
-   * Fetch friends for user id
-   * @param userId user id
-   */
-  public async fetchFriends(userId) {
-    let friends = [];
-    let cursor = -1;
-
-    while (cursor != 0) {
-      const res = await this.client.get("friends/list", {
-        user_id: userId,
-        count: 200,
-        include_user_entities: false,
-        cursor: cursor
-      });
-
-      cursor = res.data["next_cursor"];
-      friends = friends.concat(res.data["users"]);
-    }
-
-    return friends;
-  }
-
-  /**
-   * Like tweet
-   * @param tweetId tweet id
-   */
-  public async likeTweet(tweetId) {
-    return await this.client.post("favorites/create", { id: tweetId });
-  }
-
-  /**
-   * Remove like from tweet
-   * @param tweetId tweet id
-   */
-  public async unlikeTweet(tweetId) {
-    return await this.client.post("favorites/destroy", { id: tweetId });
-  }
-
-  /**
-   * Retrieve a single tweet
-   * @param tweetId tweet id
-   */
-  public async fetchTweet(tweetId) {
-    return await this.client.get("statuses/show", {
-      id: tweetId,
-      tweet_mode: "extended"
-    });
-  }
-
-  /**
-   * Search Twitter for recent tweets
-   * Since the results are loaded in batches of 20 tweets, max tweet id is a reference for the next batch
-   * @param keyword keyword
-   * @param maxId max tweet id
-   */
-  public async searchRecentTweets(keyword: string, maxId?: string) {
-    const res = await this.client.get("search/tweets", {
-      q: keyword,
-      result_type: "recent",
-      count: 20,
-      include_entities: true,
-      tweet_mode: "extended",
-      max_id: maxId
-    });
-    return res.data;
-  }
-
-  /**
-   * Search Twitter for popular tweets
-   * Since the results are loaded in batches of 20 tweets, max tweet id is a reference for the next batch
-   * @param keyword keyword
-   * @param maxId max tweet id
-   */
-  public async searchPopularTweets(keyword: string, maxId?: string) {
-    const res = await this.client.get("search/tweets", {
-      q: keyword,
-      result_type: "popular",
-      count: 20,
-      include_entities: true,
-      tweet_mode: "extended",
-      max_id: maxId
-    });
-    return res.data;
-  }
-
-  /**
-   * Search Twitter for users
-   * Since the API returns users paginated, a page has to be provided
-   * @param keyword keyword
-   * @param page page number
-   */
-  public async searchUsers(keyword: string, page?: number) {
-    const res = await this.client.get("users/search", {
-      q: keyword,
-      count: 10,
-      include_entities: true,
-      page: page
-    });
-    return res.data;
-  }
-
-  /**
-   * Updates the profile description
-   * @param description profile description
-   */
-  public async updateProfileDescription(description: string) {
-    const res = await this.client.post("account/update_profile", {
-      description: description
-    });
-    return res.data;
-  }
-}

+ 0 - 31
src1/service-worker.js

@@ -1,31 +0,0 @@
-/**
- * Check out https://googlechromelabs.github.io/sw-toolbox/ for
- * more info on how to use sw-toolbox to custom configure your service worker.
- */
-
-
-'use strict';
-importScripts('./build/sw-toolbox.js');
-
-self.toolbox.options.cache = {
-  name: 'ionic-cache'
-};
-
-// pre-cache our key assets
-self.toolbox.precache(
-  [
-    './build/main.js',
-    './build/vendor.js',
-    './build/main.css',
-    './build/polyfills.js',
-    'index.html',
-    'manifest.json'
-  ]
-);
-
-// dynamically cache any other local assets
-self.toolbox.router.any('/*', self.toolbox.fastest);
-
-// for any other requests go to the network, cache,
-// and then only use that cached resource if your user goes offline
-self.toolbox.router.default = self.toolbox.networkFirst;

+ 0 - 88
src1/theme/variables.scss

@@ -1,88 +0,0 @@
-// Ionic Variables and Theming. For more info, please see:
-// http://ionicframework.com/docs/theming/
-
-// Font path is used to include ionicons,
-// roboto, and noto sans fonts
-$font-path: "../assets/fonts";
-
-
-// The app direction is used to include
-// rtl styles in your app. For more info, please see:
-// http://ionicframework.com/docs/theming/rtl-support/
-$app-direction: ltr;
-
-
-@import "ionic.globals";
-
-
-// Shared Variables
-// --------------------------------------------------
-// To customize the look and feel of this app, you can override
-// the Sass variables found in Ionic's source scss files.
-// To view all the possible Ionic variables, see:
-// http://ionicframework.com/docs/theming/overriding-ionic-variables/
-
-
-
-
-// Named Color Variables
-// --------------------------------------------------
-// Named colors makes it easy to reuse colors on various components.
-// It's highly recommended to change the default colors
-// to match your app's branding. Ionic uses a Sass map of
-// colors so you can add, rename and remove colors as needed.
-// The "primary" color is the only required color in the map.
-
-$colors: (
-  primary:    #488aff,
-  secondary:  #32db64,
-  danger:     #f53d3d,
-  light:      #f4f4f4,
-  dark:       #222
-);
-
-
-// App iOS Variables
-// --------------------------------------------------
-// iOS only Sass variables can go here
-
-
-
-
-// App Material Design Variables
-// --------------------------------------------------
-// Material Design only Sass variables can go here
-
-
-
-
-// App Windows Variables
-// --------------------------------------------------
-// Windows only Sass variables can go here
-
-
-
-
-// App Theme
-// --------------------------------------------------
-// Ionic apps can have different themes applied, which can
-// then be future customized. This import comes last
-// so that the above variables are used and Ionic's
-// default are overridden.
-
-@import "ionic.theme.default";
-
-
-// Ionicons
-// --------------------------------------------------
-// The premium icon font for Ionic. For more info, please see:
-// http://ionicframework.com/docs/ionicons/
-
-@import "ionic.ionicons";
-
-
-// Fonts
-// --------------------------------------------------
-
-@import "roboto";
-@import "noto-sans";

Some files were not shown because too many files changed in this diff