about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/utils
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch/utils')
-rw-r--r--app/javascript/flavours/glitch/utils/base_polyfills.js47
-rw-r--r--app/javascript/flavours/glitch/utils/compare_id.js11
-rw-r--r--app/javascript/flavours/glitch/utils/extra_polyfills.js5
-rw-r--r--app/javascript/flavours/glitch/utils/is_mobile.js43
-rw-r--r--app/javascript/flavours/glitch/utils/load_keyboard_extensions.js16
-rw-r--r--app/javascript/flavours/glitch/utils/load_polyfills.js42
-rw-r--r--app/javascript/flavours/glitch/utils/main.js57
-rw-r--r--app/javascript/flavours/glitch/utils/performance.js31
-rw-r--r--app/javascript/flavours/glitch/utils/scroll.js32
-rw-r--r--app/javascript/flavours/glitch/utils/settings.js47
-rw-r--r--app/javascript/flavours/glitch/utils/stream.js265
-rw-r--r--app/javascript/flavours/glitch/utils/uuid.js3
12 files changed, 0 insertions, 599 deletions
diff --git a/app/javascript/flavours/glitch/utils/base_polyfills.js b/app/javascript/flavours/glitch/utils/base_polyfills.js
deleted file mode 100644
index 4b8123dba..000000000
--- a/app/javascript/flavours/glitch/utils/base_polyfills.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'intl';
-import 'intl/locale-data/jsonp/en';
-import 'es6-symbol/implement';
-import includes from 'array-includes';
-import assign from 'object-assign';
-import values from 'object.values';
-import isNaN from 'is-nan';
-import { decode as decodeBase64 } from './base64';
-import promiseFinally from 'promise.prototype.finally';
-
-if (!Array.prototype.includes) {
-  includes.shim();
-}
-
-if (!Object.assign) {
-  Object.assign = assign;
-}
-
-if (!Object.values) {
-  values.shim();
-}
-
-if (!Number.isNaN) {
-  Number.isNaN = isNaN;
-}
-
-promiseFinally.shim();
-
-if (!HTMLCanvasElement.prototype.toBlob) {
-  const BASE64_MARKER = ';base64,';
-
-  Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
-    value(callback, type = 'image/png', quality) {
-      const dataURL = this.toDataURL(type, quality);
-      let data;
-
-      if (dataURL.indexOf(BASE64_MARKER) >= 0) {
-        const [, base64] = dataURL.split(BASE64_MARKER);
-        data = decodeBase64(base64);
-      } else {
-        [, data] = dataURL.split(',');
-      }
-
-      callback(new Blob([data], { type }));
-    },
-  });
-}
diff --git a/app/javascript/flavours/glitch/utils/compare_id.js b/app/javascript/flavours/glitch/utils/compare_id.js
deleted file mode 100644
index 66cf51c4b..000000000
--- a/app/javascript/flavours/glitch/utils/compare_id.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export default function compareId (id1, id2) {
-  if (id1 === id2) {
-    return 0;
-  }
-
-  if (id1.length === id2.length) {
-    return id1 > id2 ? 1 : -1;
-  } else {
-    return id1.length > id2.length ? 1 : -1;
-  }
-};
diff --git a/app/javascript/flavours/glitch/utils/extra_polyfills.js b/app/javascript/flavours/glitch/utils/extra_polyfills.js
deleted file mode 100644
index 3acc55abd..000000000
--- a/app/javascript/flavours/glitch/utils/extra_polyfills.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import 'intersection-observer';
-import 'requestidlecallback';
-import objectFitImages  from 'object-fit-images';
-
-objectFitImages();
diff --git a/app/javascript/flavours/glitch/utils/is_mobile.js b/app/javascript/flavours/glitch/utils/is_mobile.js
deleted file mode 100644
index 0d5663098..000000000
--- a/app/javascript/flavours/glitch/utils/is_mobile.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import { supportsPassiveEvents } from 'detect-passive-events';
-import { forceSingleColumn } from 'flavours/glitch/initial_state';
-
-const LAYOUT_BREAKPOINT = 630;
-
-export const isMobile = width => width <= LAYOUT_BREAKPOINT;
-
-export const layoutFromWindow = (layout_local_setting) => {
-  switch (layout_local_setting) {
-  case 'multiple':
-    return 'multi-column';
-  case 'single':
-    if (isMobile(window.innerWidth)) {
-      return 'mobile';
-    } else {
-      return 'single-column';
-    }
-  default:
-    if (isMobile(window.innerWidth)) {
-      return 'mobile';
-    } else if (forceSingleColumn) {
-      return 'single-column';
-    } else {
-      return 'multi-column';
-    }
-  }
-};
-
-const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
-
-let userTouching = false;
-let listenerOptions = supportsPassiveEvents ? { passive: true } : false;
-
-const touchListener = () => {
-  userTouching = true;
-  window.removeEventListener('touchstart', touchListener, listenerOptions);
-};
-
-window.addEventListener('touchstart', touchListener, listenerOptions);
-
-export const isUserTouching = () => userTouching;
-
-export const isIOS = () => iOS;
diff --git a/app/javascript/flavours/glitch/utils/load_keyboard_extensions.js b/app/javascript/flavours/glitch/utils/load_keyboard_extensions.js
deleted file mode 100644
index 2dd0e45fa..000000000
--- a/app/javascript/flavours/glitch/utils/load_keyboard_extensions.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// On KaiOS, we may not be able to use a mouse cursor or navigate using Tab-based focus, so we install
-// special left/right focus navigation keyboard listeners, at least on public pages (i.e. so folks
-// can at least log in using KaiOS devices).
-
-function importArrowKeyNavigation() {
-  return import(/* webpackChunkName: "arrow-key-navigation" */ 'arrow-key-navigation');
-}
-
-export default function loadKeyboardExtensions() {
-  if (/KAIOS/.test(navigator.userAgent)) {
-    return importArrowKeyNavigation().then(arrowKeyNav => {
-      arrowKeyNav.register();
-    });
-  }
-  return Promise.resolve();
-}
diff --git a/app/javascript/flavours/glitch/utils/load_polyfills.js b/app/javascript/flavours/glitch/utils/load_polyfills.js
deleted file mode 100644
index 73eedc9dc..000000000
--- a/app/javascript/flavours/glitch/utils/load_polyfills.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Convenience function to load polyfills and return a promise when it's done.
-// If there are no polyfills, then this is just Promise.resolve() which means
-// it will execute in the same tick of the event loop (i.e. near-instant).
-
-function importBasePolyfills() {
-  return import(/* webpackChunkName: "base_polyfills" */ './base_polyfills');
-}
-
-function importExtraPolyfills() {
-  return import(/* webpackChunkName: "extra_polyfills" */ './extra_polyfills');
-}
-
-function loadPolyfills() {
-  const needsBasePolyfills = !(
-    Array.prototype.includes &&
-    HTMLCanvasElement.prototype.toBlob &&
-    window.Intl &&
-    Number.isNaN &&
-    Object.assign &&
-    Object.values &&
-    window.Symbol &&
-    Promise.prototype.finally
-  );
-
-  // Latest version of Firefox and Safari do not have IntersectionObserver.
-  // Edge does not have requestIdleCallback and object-fit CSS property.
-  // This avoids shipping them all the polyfills.
-  const needsExtraPolyfills = !(
-    window.IntersectionObserver &&
-    window.IntersectionObserverEntry &&
-    'isIntersecting' in IntersectionObserverEntry.prototype &&
-    window.requestIdleCallback &&
-    'object-fit' in (new Image()).style
-  );
-
-  return Promise.all([
-    needsBasePolyfills && importBasePolyfills(),
-    needsExtraPolyfills && importExtraPolyfills(),
-  ]);
-}
-
-export default loadPolyfills;
diff --git a/app/javascript/flavours/glitch/utils/main.js b/app/javascript/flavours/glitch/utils/main.js
deleted file mode 100644
index 39a46db00..000000000
--- a/app/javascript/flavours/glitch/utils/main.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { setupBrowserNotifications } from 'flavours/glitch/actions/notifications';
-import Mastodon, { store } from 'flavours/glitch/containers/mastodon';
-import ready from 'flavours/glitch/ready';
-
-const perf = require('flavours/glitch/utils/performance');
-
-/**
- * @returns {Promise<void>}
- */
-function main() {
-  perf.start('main()');
-
-  if (window.history && history.replaceState) {
-    const { pathname, search, hash } = window.location;
-    const path = pathname + search + hash;
-    if (!(/^\/web($|\/)/).test(path)) {
-      history.replaceState(null, document.title, `/web${path}`);
-    }
-  }
-
-  return ready(async () => {
-    const mountNode = document.getElementById('mastodon');
-    const props = JSON.parse(mountNode.getAttribute('data-props'));
-
-    ReactDOM.render(<Mastodon {...props} />, mountNode);
-    store.dispatch(setupBrowserNotifications());
-
-    if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
-      const [{ Workbox }, { me }] = await Promise.all([
-        import('workbox-window'),
-        import('mastodon/initial_state'),
-      ]);
-
-      const wb = new Workbox('/sw.js');
-
-      try {
-        await wb.register();
-      } catch (err) {
-        console.error(err);
-
-        return;
-      }
-
-      if (me) {
-        const registerPushNotifications = await import('flavours/glitch/actions/push_notifications');
-
-        store.dispatch(registerPushNotifications.register());
-      }
-    }
-
-    perf.stop('main()');
-  });
-}
-
-export default main;
diff --git a/app/javascript/flavours/glitch/utils/performance.js b/app/javascript/flavours/glitch/utils/performance.js
deleted file mode 100644
index 450a90626..000000000
--- a/app/javascript/flavours/glitch/utils/performance.js
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Tools for performance debugging, only enabled in development mode.
-// Open up Chrome Dev Tools, then Timeline, then User Timing to see output.
-// Also see config/webpack/loaders/mark.js for the webpack loader marks.
-//
-
-let marky;
-
-if (process.env.NODE_ENV === 'development') {
-  if (typeof performance !== 'undefined' && performance.setResourceTimingBufferSize) {
-    // Increase Firefox's performance entry limit; otherwise it's capped to 150.
-    // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1331135
-    performance.setResourceTimingBufferSize(Infinity);
-  }
-  marky = require('marky');
-  // allows us to easily do e.g. ReactPerf.printWasted() while debugging
-  //window.ReactPerf = require('react-addons-perf');
-  //window.ReactPerf.start();
-}
-
-export function start(name) {
-  if (process.env.NODE_ENV === 'development') {
-    marky.mark(name);
-  }
-}
-
-export function stop(name) {
-  if (process.env.NODE_ENV === 'development') {
-    marky.stop(name);
-  }
-}
diff --git a/app/javascript/flavours/glitch/utils/scroll.js b/app/javascript/flavours/glitch/utils/scroll.js
deleted file mode 100644
index 84fe58269..000000000
--- a/app/javascript/flavours/glitch/utils/scroll.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const easingOutQuint = (x, t, b, c, d) => c * ((t = t / d - 1) * t * t * t * t + 1) + b;
-
-const scroll = (node, key, target) => {
-  const startTime = Date.now();
-  const offset    = node[key];
-  const gap       = target - offset;
-  const duration  = 1000;
-  let interrupt   = false;
-
-  const step = () => {
-    const elapsed    = Date.now() - startTime;
-    const percentage = elapsed / duration;
-
-    if (percentage > 1 || interrupt) {
-      return;
-    }
-
-    node[key] = easingOutQuint(0, elapsed, offset, gap, duration);
-    requestAnimationFrame(step);
-  };
-
-  step();
-
-  return () => {
-    interrupt = true;
-  };
-};
-
-const isScrollBehaviorSupported = 'scrollBehavior' in document.documentElement.style;
-
-export const scrollRight = (node, position) => isScrollBehaviorSupported ? node.scrollTo({ left: position, behavior: 'smooth' }) : scroll(node, 'scrollLeft', position);
-export const scrollTop = (node) => isScrollBehaviorSupported ? node.scrollTo({ top: 0, behavior: 'smooth' }) : scroll(node, 'scrollTop', 0);
diff --git a/app/javascript/flavours/glitch/utils/settings.js b/app/javascript/flavours/glitch/utils/settings.js
deleted file mode 100644
index 7643a508e..000000000
--- a/app/javascript/flavours/glitch/utils/settings.js
+++ /dev/null
@@ -1,47 +0,0 @@
-export default class Settings {
-
-  constructor(keyBase = null) {
-    this.keyBase = keyBase;
-  }
-
-  generateKey(id) {
-    return this.keyBase ? [this.keyBase, `id${id}`].join('.') : id;
-  }
-
-  set(id, data) {
-    const key = this.generateKey(id);
-    try {
-      const encodedData = JSON.stringify(data);
-      localStorage.setItem(key, encodedData);
-      return data;
-    } catch (e) {
-      return null;
-    }
-  }
-
-  get(id) {
-    const key = this.generateKey(id);
-    try {
-      const rawData = localStorage.getItem(key);
-      return JSON.parse(rawData);
-    } catch (e) {
-      return null;
-    }
-  }
-
-  remove(id) {
-    const data = this.get(id);
-    if (data) {
-      const key = this.generateKey(id);
-      try {
-        localStorage.removeItem(key);
-      } catch (e) {
-      }
-    }
-    return data;
-  }
-
-}
-
-export const pushNotificationsSetting = new Settings('mastodon_push_notification_data');
-export const tagHistory = new Settings('mastodon_tag_history');
diff --git a/app/javascript/flavours/glitch/utils/stream.js b/app/javascript/flavours/glitch/utils/stream.js
deleted file mode 100644
index c6d12cd6f..000000000
--- a/app/javascript/flavours/glitch/utils/stream.js
+++ /dev/null
@@ -1,265 +0,0 @@
-// @ts-check
-
-import WebSocketClient from '@gamestdio/websocket';
-
-/**
- * @type {WebSocketClient | undefined}
- */
-let sharedConnection;
-
-/**
- * @typedef Subscription
- * @property {string} channelName
- * @property {Object.<string, string>} params
- * @property {function(): void} onConnect
- * @property {function(StreamEvent): void} onReceive
- * @property {function(): void} onDisconnect
- */
-
-/**
-  * @typedef StreamEvent
-  * @property {string} event
-  * @property {object} payload
-  */
-
-/**
- * @type {Array.<Subscription>}
- */
-const subscriptions = [];
-
-/**
- * @type {Object.<string, number>}
- */
-const subscriptionCounters = {};
-
-/**
- * @param {Subscription} subscription
- */
-const addSubscription = subscription => {
-  subscriptions.push(subscription);
-};
-
-/**
- * @param {Subscription} subscription
- */
-const removeSubscription = subscription => {
-  const index = subscriptions.indexOf(subscription);
-
-  if (index !== -1) {
-    subscriptions.splice(index, 1);
-  }
-};
-
-/**
- * @param {Subscription} subscription
- */
-const subscribe = ({ channelName, params, onConnect }) => {
-  const key = channelNameWithInlineParams(channelName, params);
-
-  subscriptionCounters[key] = subscriptionCounters[key] || 0;
-
-  if (subscriptionCounters[key] === 0) {
-    sharedConnection.send(JSON.stringify({ type: 'subscribe', stream: channelName, ...params }));
-  }
-
-  subscriptionCounters[key] += 1;
-  onConnect();
-};
-
-/**
- * @param {Subscription} subscription
- */
-const unsubscribe = ({ channelName, params, onDisconnect }) => {
-  const key = channelNameWithInlineParams(channelName, params);
-
-  subscriptionCounters[key] = subscriptionCounters[key] || 1;
-
-  if (subscriptionCounters[key] === 1 && sharedConnection.readyState === WebSocketClient.OPEN) {
-    sharedConnection.send(JSON.stringify({ type: 'unsubscribe', stream: channelName, ...params }));
-  }
-
-  subscriptionCounters[key] -= 1;
-  onDisconnect();
-};
-
-const sharedCallbacks = {
-  connected () {
-    subscriptions.forEach(subscription => subscribe(subscription));
-  },
-
-  received (data) {
-    const { stream } = data;
-
-    subscriptions.filter(({ channelName, params }) => {
-      const streamChannelName = stream[0];
-
-      if (stream.length === 1) {
-        return channelName === streamChannelName;
-      }
-
-      const streamIdentifier = stream[1];
-
-      if (['hashtag', 'hashtag:local'].includes(channelName)) {
-        return channelName === streamChannelName && params.tag === streamIdentifier;
-      } else if (channelName === 'list') {
-        return channelName === streamChannelName && params.list === streamIdentifier;
-      }
-
-      return false;
-    }).forEach(subscription => {
-      subscription.onReceive(data);
-    });
-  },
-
-  disconnected () {
-    subscriptions.forEach(subscription => unsubscribe(subscription));
-  },
-
-  reconnected () {
-  },
-};
-
-/**
- * @param {string} channelName
- * @param {Object.<string, string>} params
- * @return {string}
- */
-const channelNameWithInlineParams = (channelName, params) => {
-  if (Object.keys(params).length === 0) {
-    return channelName;
-  }
-
-  return `${channelName}&${Object.keys(params).map(key => `${key}=${params[key]}`).join('&')}`;
-};
-
-/**
- * @param {string} channelName
- * @param {Object.<string, string>} params
- * @param {function(Function, Function): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks
- * @return {function(): void}
- */
-export const connectStream = (channelName, params, callbacks) => (dispatch, getState) => {
-  const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
-  const accessToken = getState().getIn(['meta', 'access_token']);
-  const { onConnect, onReceive, onDisconnect } = callbacks(dispatch, getState);
-
-  // If we cannot use a websockets connection, we must fall back
-  // to using individual connections for each channel
-  if (!streamingAPIBaseURL.startsWith('ws')) {
-    const connection = createConnection(streamingAPIBaseURL, accessToken, channelNameWithInlineParams(channelName, params), {
-      connected () {
-        onConnect();
-      },
-
-      received (data) {
-        onReceive(data);
-      },
-
-      disconnected () {
-        onDisconnect();
-      },
-
-      reconnected () {
-        onConnect();
-      },
-    });
-
-    return () => {
-      connection.close();
-    };
-  }
-
-  const subscription = {
-    channelName,
-    params,
-    onConnect,
-    onReceive,
-    onDisconnect,
-  };
-
-  addSubscription(subscription);
-
-  // If a connection is open, we can execute the subscription right now. Otherwise,
-  // because we have already registered it, it will be executed on connect
-
-  if (!sharedConnection) {
-    sharedConnection = /** @type {WebSocketClient} */ (createConnection(streamingAPIBaseURL, accessToken, '', sharedCallbacks));
-  } else if (sharedConnection.readyState === WebSocketClient.OPEN) {
-    subscribe(subscription);
-  }
-
-  return () => {
-    removeSubscription(subscription);
-    unsubscribe(subscription);
-  };
-};
-
-const KNOWN_EVENT_TYPES = [
-  'update',
-  'delete',
-  'notification',
-  'conversation',
-  'filters_changed',
-  'encrypted_message',
-  'announcement',
-  'announcement.delete',
-  'announcement.reaction',
-];
-
-/**
- * @param {MessageEvent} e
- * @param {function(StreamEvent): void} received
- */
-const handleEventSourceMessage = (e, received) => {
-  received({
-    event: e.type,
-    payload: e.data,
-  });
-};
-
-/**
- * @param {string} streamingAPIBaseURL
- * @param {string} accessToken
- * @param {string} channelName
- * @param {{ connected: Function, received: function(StreamEvent): void, disconnected: Function, reconnected: Function }} callbacks
- * @return {WebSocketClient | EventSource}
- */
-const createConnection = (streamingAPIBaseURL, accessToken, channelName, { connected, received, disconnected, reconnected }) => {
-  const params = channelName.split('&');
-
-  channelName = params.shift();
-
-  if (streamingAPIBaseURL.startsWith('ws')) {
-    const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken);
-
-    ws.onopen      = connected;
-    ws.onmessage   = e => received(JSON.parse(e.data));
-    ws.onclose     = disconnected;
-    ws.onreconnect = reconnected;
-
-    return ws;
-  }
-
-  channelName = channelName.replace(/:/g, '/');
-
-  if (channelName.endsWith(':media')) {
-    channelName = channelName.replace('/media', '');
-    params.push('only_media=true');
-  }
-
-  params.push(`access_token=${accessToken}`);
-
-  const es = new EventSource(`${streamingAPIBaseURL}/api/v1/streaming/${channelName}?${params.join('&')}`);
-
-  es.onopen = () => {
-    connected();
-  };
-
-  KNOWN_EVENT_TYPES.forEach(type => {
-    es.addEventListener(type, e => handleEventSourceMessage(/** @type {MessageEvent} */ (e), received));
-  });
-
-  es.onerror = /** @type {function(): void} */ (disconnected);
-
-  return es;
-};
diff --git a/app/javascript/flavours/glitch/utils/uuid.js b/app/javascript/flavours/glitch/utils/uuid.js
deleted file mode 100644
index be1899305..000000000
--- a/app/javascript/flavours/glitch/utils/uuid.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function uuid(a) {
-  return a ? (a^Math.random() * 16 >> a / 4).toString(16) : ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, uuid);
-};