Browse Source

fix(random): Patch and tweak.

jackyalcine 11 months ago
parent
commit
c86ed8564e
Signed by: Jacky Alciné <yo@jacky.wtf> GPG Key ID: 36CD7728BDFD66FF
53 changed files with 296 additions and 589 deletions
  1. 5
    6
      .browserslistrc
  2. 1
    1
      .node-version
  3. 2
    13
      .postcssrc.js
  4. 24
    6
      .sassrc.js
  5. 1
    1
      config/config.exs
  6. 1
    0
      lib/indieweb/post.ex
  7. 3
    5
      lib/storage/image.ex
  8. 1
    0
      lib/web.ex
  9. 1
    0
      mix.exs
  10. 1
    0
      mix.lock
  11. 0
    160
      package-lock.json
  12. 2
    3
      package.json
  13. 1
    1
      test/fixtures/vcr_cassettes/fails_to_fetch_due_to_network_error.json
  14. 1
    1
      test/fixtures/vcr_cassettes/fails_to_fetch_due_to_server_error.json
  15. 1
    47
      test/fixtures/vcr_cassettes/fetch_from_page.json
  16. 1
    46
      test/fixtures/vcr_cassettes/page_is_empty.json
  17. 2
    2
      test/fixtures/vcr_cassettes/refresh_of_mf2_data.json
  18. 1
    1
      test/fixtures/vcr_cassettes/relme_failing_endpoint.json
  19. 1
    1
      test/fixtures/vcr_cassettes/relme_success.json
  20. 17
    8
      test/fixtures/vcr_cassettes/webmention_send_success.json
  21. 0
    51
      test/fixtures/vcr_cassettes/webmention_test_for_headers.json
  22. 1
    1
      test/fixtures/vcr_cassettes/webmention_test_for_headers_1.json
  23. 1
    1
      test/fixtures/vcr_cassettes/webmention_test_for_headers_2.json
  24. 1
    1
      test/fixtures/vcr_cassettes/webmention_test_for_headers_3.json
  25. 1
    50
      test/fixtures/vcr_cassettes/webmention_test_for_headers_4.json
  26. 2
    2
      test/integration/views/error_view_test.exs
  27. 14
    14
      test/unit/indieweb/micropub/entry_test.exs
  28. 2
    1
      test/unit/timeline_test.exs
  29. 12
    0
      web/controllers/entry_controller.ex
  30. 5
    4
      web/controllers/fallback_controller.ex
  31. 3
    9
      web/controllers/page_controller.ex
  32. 1
    1
      web/endpoint.ex
  33. 0
    1
      web/router.ex
  34. 15
    44
      web/static/css/koype.scss
  35. 1
    1
      web/static/css/vendor.scss
  36. 1
    0
      web/static/images/background-wiggle.svg
  37. 1
    1
      web/templates/entry/_sparkline.html.eex
  38. 0
    13
      web/templates/entry/index.html.eex
  39. 4
    0
      web/templates/entry/stream-empty.html.eex
  40. 53
    0
      web/templates/entry/stream.html.eex
  41. 0
    0
      web/templates/entry/stream_inline-contextual.html.eex
  42. 0
    0
      web/templates/entry/stream_inline-media.html.eex
  43. 0
    0
      web/templates/entry/stream_inline-single.html.eex
  44. 1
    1
      web/templates/error/500.html.eex
  45. 6
    4
      web/templates/layout/app.html.eex
  46. 4
    4
      web/templates/layout/simple.html.eex
  47. 19
    28
      web/templates/page/_footer.html.eex
  48. 4
    4
      web/templates/page/_header.html.eex
  49. 0
    4
      web/templates/page/stream-empty.html.eex
  50. 0
    44
      web/templates/page/stream.html.eex
  51. 1
    1
      web/templates/setup/view.html.eex
  52. 76
    0
      web/views/entry_view.ex
  53. 0
    2
      web/views/page_view.ex

+ 5
- 6
.browserslistrc View File

@@ -1,6 +1,5 @@
1
-last 2 Chrome versions
2
-last 2 Firefox versions
3
-last 2 Safari versions
4
-last 2 Edge versions
5
-last 4 iOS versions
6
-last 2 ChromeAndroid versions
1
+last 10 Chrome versions
2
+last 10 ChromeAndroid versions
3
+last 10 Firefox versions
4
+last 5 Safari versions
5
+last 5 iOS versions

+ 1
- 1
.node-version View File

@@ -1 +1 @@
1
-8.14.0
1
+10.14.2

+ 2
- 13
.postcssrc.js View File

@@ -8,18 +8,12 @@ module.exports = {
8 8
       clearMessages: false
9 9
     },
10 10
     autoprefixer: {},
11
+    /*
11 12
     'postcss-strip-inline-comments': {},
12 13
     'postcss-ordered-values': {},
13 14
     'postcss-reduce-initial': {},
14 15
     'postcss-combine-duplicated-selectors': {},
15 16
     'postcss-fontpath': [],
16
-    'postcss-urlrewrite': {
17
-      imports: true,
18
-      rules: [{
19
-        from: /css\/images/,
20
-        to: '/assets/images/'
21
-      }]
22
-    },
23 17
     'postcss-pxtorem': {
24 18
       unitPrecision: 8,
25 19
       propWhiteList: [],
@@ -39,14 +33,9 @@ module.exports = {
39 33
       ]
40 34
     } : false,
41 35
     'css-mqpacker': [],
42
-    'postcss-url': [{
43
-      filter: './css/images/*',
44
-      url: 'copy',
45
-      assetsPath: './',
46
-      useHash: true
47
-    }, ],
48 36
     'mdcss': {
49 37
       theme: require('mdcss-theme-github')
50 38
     }
39
+    */
51 40
   }
52 41
 };

+ 24
- 6
.sassrc.js View File

@@ -1,15 +1,33 @@
1 1
 const path = require('path')
2 2
 const CWD = process.cwd()
3
-const eyeglass = require('eyeglass');
3
+const Eyeglass = require('eyeglass');
4
+var assetsDir = path.join(CWD, "web", "static");
5
+var buildDir = path.join(CWD, "priv", "static", "assets");
4 6
 
5
-module.exports = eyeglass({
7
+const options = {
6 8
   "includePaths": [
7 9
     path.resolve(CWD, 'node_modules'),
8 10
     path.resolve(CWD, 'web/static/css')
9 11
   ],
10
-  "sourceMap": true,
11
-  "eyeglass": {
12
-    root: CWD,
13
-    buildDir: path.resolve(CWD, "priv/static/assets"),
12
+  "relativeUrls": true,
13
+  "engines": {
14
+    "sass": require("sass"),
14 15
   }
16
+}
17
+
18
+const eyeglass = new Eyeglass({
19
+  eyeglass: {
20
+    assets: {
21
+      sources: [
22
+        {
23
+          directory: path.resolve(assetsDir)
24
+        }
25
+      ]
26
+    },
27
+    buildDir,
28
+    root: CWD,
29
+  },
30
+  ...options
15 31
 });
32
+
33
+module.exports = eyeglass.sassOptions();

+ 1
- 1
config/config.exs View File

@@ -17,7 +17,7 @@ config :koype, Koype.Web.Endpoint,
17 17
   url: nil,
18 18
   http: [port: {:system, :integer, "PORT", 5000}],
19 19
   secret_key_base: {:system, :string, "SECRET_KEY_BASE"},
20
-  render_errors: [view: Koype.Web.ErrorView, accepts: ~w(html)],
20
+  render_errors: [view: Koype.Web.ErrorView, layout: "simple.html", accepts: ~w(html)],
21 21
   pubsub: [name: Koype.PubSub, adapter: Phoenix.PubSub.PG2],
22 22
   server: true
23 23
 

+ 1
- 0
lib/indieweb/post.ex View File

@@ -27,6 +27,7 @@ defmodule IndieWeb.Post do
27 27
     |> Floki.find("a")
28 28
     |> Floki.attribute("href")
29 29
   end
30
+  def extract_uris(:note, _), do: []
30 31
 
31 32
   def extract_uris(:bookmark, %{"bookmark-of" => uri} = properties) do
32 33
     [uri] ++ extract_uris(:note, properties)

+ 3
- 5
lib/storage/image.ex View File

@@ -7,6 +7,7 @@ defmodule Koype.Storage.Image do
7 7
   @extension_whitelist ~w(.jpg .jpeg .gif .png .webp .bmp .apng)
8 8
   @acl :public_read
9 9
 
10
+  def storage_dir(version, args)
10 11
   def storage_dir(_version, {_file, %{id: id, __meta__: meta}}) do
11 12
     {_, folder_name} = meta.source
12 13
     Path.join(["images", folder_name, id])
@@ -14,12 +15,14 @@ defmodule Koype.Storage.Image do
14 15
 
15 16
   def storage_dir(_version, {_file, :floating}), do: "images/floating"
16 17
 
18
+  def filename(version, args)
17 19
   def filename(version, {%{filename: filename} = _file, _scope}),
18 20
     do: "#{version}_#{filename}"
19 21
 
20 22
   def filename(version, {%{file_name: filename} = _file, _scope}),
21 23
     do: "#{version}_#{filename}"
22 24
 
25
+  def validate(args)
23 26
   def validate({%{filename: filename} = _file, _}) do
24 27
     file_extension = filename |> Path.extname() |> String.downcase()
25 28
     Enum.member?(@extension_whitelist, file_extension)
@@ -30,11 +33,6 @@ defmodule Koype.Storage.Image do
30 33
     Enum.member?(@extension_whitelist, file_extension)
31 34
   end
32 35
 
33
-  def validate({%{file_name: filename} = _file, _}) do
34
-    file_extension = filename |> Path.extname() |> String.downcase()
35
-    Enum.member?(@extension_whitelist, file_extension)
36
-  end
37
-
38 36
   # NOTE: Fetch all URIs from Arc.
39 37
   # NOTE: Inject information about:
40 38
   #   - dimensions

+ 1
- 0
lib/web.ex View File

@@ -25,6 +25,7 @@ defmodule Koype.Web do
25 25
       import Koype.Web.AuthenticationHelpers
26 26
 
27 27
       def tag({:meta, :application_name}, _template, _assigns), do: "Koype"
28
+      def tag({:meta, :description}, _template, _assigns), do: "IndieWeb under your control."
28 29
       def tag({:meta, :creator}, template, assigns), do: tag({:meta, :author}, template, assigns)
29 30
 
30 31
       def tag({:link, :authorization_endpoint}, _template, _assigns),

+ 1
- 0
mix.exs View File

@@ -101,6 +101,7 @@ defmodule Koype.Mixfile do
101 101
       {:pretty_print_formatter, "~> 0.1.5", only: :dev},
102 102
       {:redix, "~> 0.8.0"},
103 103
       {:scrivener_ecto, "~> 1.0"},
104
+      {:scrivener_headers, "~> 3.1"},
104 105
       {:seedex, "~> 0.1.2"},
105 106
       {:sobelow, "~> 0.7.1"},
106 107
       {:sqlite_ecto2, "~> 2.2.5"},

+ 1
- 0
mix.lock View File

@@ -86,6 +86,7 @@
86 86
   "sbroker": {:hex, :sbroker, "1.0.0", "28ff1b5e58887c5098539f236307b36fe1d3edaa2acff9d6a3d17c2dcafebbd0", [:rebar3], [], "hexpm"},
87 87
   "scrivener": {:hex, :scrivener, "2.5.0", "e1f78c62b6806d91cc9c4778deef1ea4e80aa9fadfce2c16831afe0468cc8a2c", [:mix], [], "hexpm"},
88 88
   "scrivener_ecto": {:hex, :scrivener_ecto, "1.3.0", "69698428e22810ac8a47abc12d1df5b2f5d8f6b36dc5d5bfe6dd93fde857c576", [:mix], [{:ecto, "~> 2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.11.0 or ~> 0.12.0 or ~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:scrivener, "~> 2.4", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm"},
89
+  "scrivener_headers": {:hex, :scrivener_headers, "3.1.1", "432784685a357953ba482b85848d7a6549e3e24d2a3858af33b567c50ed889ee", [:mix], [{:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: true]}, {:scrivener, "~> 2.3", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm"},
89 90
   "seedex": {:hex, :seedex, "0.1.4", "29ec6518964689dd6da2d285b622cfdcbe950954539e9bbcac9ee653f49d7b68", [:mix], [{:ecto, "~> 1.1 or ~> 2.1", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm"},
90 91
   "sobelow": {:hex, :sobelow, "0.7.1", "01a52ea8a19be0aa41ce969746f057e90f3994f1607c771968359718bd0e6988", [:mix], [], "hexpm"},
91 92
   "sqlite_ecto2": {:hex, :sqlite_ecto2, "2.2.5", "f111a48188b0640effb7f2952071c4cf285501d3ce090820a7c2fc20af3867e9", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "2.2.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: false]}, {:sqlitex, "~> 1.4", [hex: :sqlitex, repo: "hexpm", optional: false]}], "hexpm"},

+ 0
- 160
package-lock.json View File

@@ -3037,12 +3037,6 @@
3037 3037
       "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
3038 3038
       "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
3039 3039
     },
3040
-    "es6-promise": {
3041
-      "version": "4.2.5",
3042
-      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
3043
-      "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
3044
-      "dev": true
3045
-    },
3046 3040
     "escape-html": {
3047 3041
       "version": "1.0.3",
3048 3042
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3360,29 +3354,6 @@
3360 3354
         }
3361 3355
       }
3362 3356
     },
3363
-    "extract-zip": {
3364
-      "version": "1.6.7",
3365
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
3366
-      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
3367
-      "dev": true,
3368
-      "requires": {
3369
-        "concat-stream": "1.6.2",
3370
-        "debug": "2.6.9",
3371
-        "mkdirp": "0.5.1",
3372
-        "yauzl": "2.4.1"
3373
-      },
3374
-      "dependencies": {
3375
-        "debug": {
3376
-          "version": "2.6.9",
3377
-          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
3378
-          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
3379
-          "dev": true,
3380
-          "requires": {
3381
-            "ms": "2.0.0"
3382
-          }
3383
-        }
3384
-      }
3385
-    },
3386 3357
     "extsprintf": {
3387 3358
       "version": "1.3.0",
3388 3359
       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -3488,15 +3459,6 @@
3488 3459
         "bser": "^2.0.0"
3489 3460
       }
3490 3461
     },
3491
-    "fd-slicer": {
3492
-      "version": "1.0.1",
3493
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
3494
-      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
3495
-      "dev": true,
3496
-      "requires": {
3497
-        "pend": "~1.2.0"
3498
-      }
3499
-    },
3500 3462
     "feather-icons": {
3501 3463
       "version": "4.9.0",
3502 3464
       "resolved": "https://registry.npmjs.org/feather-icons/-/feather-icons-4.9.0.tgz",
@@ -4547,16 +4509,6 @@
4547 4509
         "minimalistic-assert": "^1.0.1"
4548 4510
       }
4549 4511
     },
4550
-    "hasha": {
4551
-      "version": "2.2.0",
4552
-      "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
4553
-      "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
4554
-      "dev": true,
4555
-      "requires": {
4556
-        "is-stream": "^1.0.1",
4557
-        "pinkie-promise": "^2.0.0"
4558
-      }
4559
-    },
4560 4512
     "hex-color-regex": {
4561 4513
       "version": "1.1.0",
4562 4514
       "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
@@ -6993,26 +6945,11 @@
6993 6945
         "verror": "1.10.0"
6994 6946
       }
6995 6947
     },
6996
-    "kew": {
6997
-      "version": "0.7.0",
6998
-      "resolved": "http://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
6999
-      "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
7000
-      "dev": true
7001
-    },
7002 6948
     "kind-of": {
7003 6949
       "version": "6.0.2",
7004 6950
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
7005 6951
       "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
7006 6952
     },
7007
-    "klaw": {
7008
-      "version": "1.3.1",
7009
-      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
7010
-      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
7011
-      "dev": true,
7012
-      "requires": {
7013
-        "graceful-fs": "^4.1.9"
7014
-      }
7015
-    },
7016 6953
     "kleur": {
7017 6954
       "version": "2.0.2",
7018 6955
       "resolved": "https://registry.npmjs.org/kleur/-/kleur-2.0.2.tgz",
@@ -8381,57 +8318,12 @@
8381 8318
         "sha.js": "^2.4.8"
8382 8319
       }
8383 8320
     },
8384
-    "pend": {
8385
-      "version": "1.2.0",
8386
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
8387
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
8388
-      "dev": true
8389
-    },
8390 8321
     "performance-now": {
8391 8322
       "version": "2.1.0",
8392 8323
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
8393 8324
       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
8394 8325
       "dev": true
8395 8326
     },
8396
-    "phantomjs-prebuilt": {
8397
-      "version": "2.1.16",
8398
-      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
8399
-      "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
8400
-      "dev": true,
8401
-      "requires": {
8402
-        "es6-promise": "^4.0.3",
8403
-        "extract-zip": "^1.6.5",
8404
-        "fs-extra": "^1.0.0",
8405
-        "hasha": "^2.2.0",
8406
-        "kew": "^0.7.0",
8407
-        "progress": "^1.1.8",
8408
-        "request": "^2.81.0",
8409
-        "request-progress": "^2.0.1",
8410
-        "which": "^1.2.10"
8411
-      },
8412
-      "dependencies": {
8413
-        "fs-extra": {
8414
-          "version": "1.0.0",
8415
-          "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
8416
-          "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
8417
-          "dev": true,
8418
-          "requires": {
8419
-            "graceful-fs": "^4.1.2",
8420
-            "jsonfile": "^2.1.0",
8421
-            "klaw": "^1.0.0"
8422
-          }
8423
-        },
8424
-        "jsonfile": {
8425
-          "version": "2.4.0",
8426
-          "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
8427
-          "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
8428
-          "dev": true,
8429
-          "requires": {
8430
-            "graceful-fs": "^4.1.6"
8431
-          }
8432
-        }
8433
-      }
8434
-    },
8435 8327
     "phoenix": {
8436 8328
       "version": "file:deps/phoenix"
8437 8329
     },
@@ -9262,28 +9154,6 @@
9262 9154
         "postcss-value-parser": "^3.0.0"
9263 9155
       }
9264 9156
     },
9265
-    "postcss-plugin": {
9266
-      "version": "1.0.0",
9267
-      "resolved": "https://registry.npmjs.org/postcss-plugin/-/postcss-plugin-1.0.0.tgz",
9268
-      "integrity": "sha1-92OBRWW4e5PhNEn8+ddZQcVmsHA=",
9269
-      "dev": true,
9270
-      "requires": {
9271
-        "postcss": "^6.0.8"
9272
-      },
9273
-      "dependencies": {
9274
-        "postcss": {
9275
-          "version": "6.0.23",
9276
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
9277
-          "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
9278
-          "dev": true,
9279
-          "requires": {
9280
-            "chalk": "^2.4.1",
9281
-            "source-map": "^0.6.1",
9282
-            "supports-color": "^5.4.0"
9283
-          }
9284
-        }
9285
-      }
9286
-    },
9287 9157
     "postcss-pxtorem": {
9288 9158
       "version": "4.0.1",
9289 9159
       "resolved": "https://registry.npmjs.org/postcss-pxtorem/-/postcss-pxtorem-4.0.1.tgz",
@@ -9829,12 +9699,6 @@
9829 9699
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
9830 9700
       "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
9831 9701
     },
9832
-    "progress": {
9833
-      "version": "1.1.8",
9834
-      "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
9835
-      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
9836
-      "dev": true
9837
-    },
9838 9702
     "promise-polyfill": {
9839 9703
       "version": "6.1.0",
9840 9704
       "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
@@ -10303,15 +10167,6 @@
10303 10167
         "uuid": "^3.3.2"
10304 10168
       }
10305 10169
     },
10306
-    "request-progress": {
10307
-      "version": "2.0.1",
10308
-      "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
10309
-      "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
10310
-      "dev": true,
10311
-      "requires": {
10312
-        "throttleit": "^1.0.0"
10313
-      }
10314
-    },
10315 10170
     "request-promise-core": {
10316 10171
       "version": "1.1.1",
10317 10172
       "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
@@ -11766,12 +11621,6 @@
11766 11621
       "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=",
11767 11622
       "dev": true
11768 11623
     },
11769
-    "throttleit": {
11770
-      "version": "1.0.0",
11771
-      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
11772
-      "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
11773
-      "dev": true
11774
-    },
11775 11624
     "through": {
11776 11625
       "version": "2.3.8",
11777 11626
       "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -12738,15 +12587,6 @@
12738 12587
         }
12739 12588
       }
12740 12589
     },
12741
-    "yauzl": {
12742
-      "version": "2.4.1",
12743
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
12744
-      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
12745
-      "dev": true,
12746
-      "requires": {
12747
-        "fd-slicer": "~1.0.1"
12748
-      }
12749
-    },
12750 12590
     "yn": {
12751 12591
       "version": "2.0.0",
12752 12592
       "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",

+ 2
- 3
package.json View File

@@ -8,8 +8,8 @@
8 8
     "test": "test/web"
9 9
   },
10 10
   "scripts": {
11
-    "parcel:watch": "parcel serve web/static/js/*.ts web/static/css/*.scss --out-dir priv/static/assets --public-url ./ --cache-dir tmp/parcel --no-cache --log-level 5 --global Koype",
12
-    "parcel:build": "parcel build web/static/js/*.ts web/static/css/*.scss --out-dir priv/static/assets --public-url ./ --cache-dir tmp/parcel --no-cache --log-level 4 --global Koype --detailed-report",
11
+    "parcel:watch": "parcel serve web/static/js/*.ts web/static/css/*.scss --out-dir priv/static/assets --cache-dir tmp/parcel --no-cache --log-level 5 --global Koype",
12
+    "parcel:build": "parcel build web/static/js/*.ts web/static/css/*.scss --out-dir priv/static/assets --cache-dir tmp/parcel --no-cache --log-level 4 --global Koype --detailed-report",
13 13
     "test": "jest"
14 14
   },
15 15
   "repository": {
@@ -65,7 +65,6 @@
65 65
     "postcss-fontpath": "^1.0.0",
66 66
     "postcss-hash": "^1.0.2",
67 67
     "postcss-import": "12.0.1",
68
-    "postcss-plugin": "^1.0.0",
69 68
     "postcss-pxtorem": "^4.0.1",
70 69
     "postcss-url": "^8.0.0",
71 70
     "postcss-urlrewrite": "^0.2.2",

+ 1
- 1
test/fixtures/vcr_cassettes/fails_to_fetch_due_to_network_error.json View File

@@ -32,7 +32,7 @@
32 32
       "headers": {
33 33
         "Connection": "keep-alive",
34 34
         "Server": "gunicorn/19.9.0",
35
-        "Date": "Sun, 30 Dec 2018 17:30:26 GMT",
35
+        "Date": "Mon, 31 Dec 2018 09:40:32 GMT",
36 36
         "Content-Type": "text/html; charset=utf-8",
37 37
         "Access-Control-Allow-Origin": "*",
38 38
         "Access-Control-Allow-Credentials": "true",

+ 1
- 1
test/fixtures/vcr_cassettes/fails_to_fetch_due_to_server_error.json View File

@@ -32,7 +32,7 @@
32 32
       "headers": {
33 33
         "Connection": "keep-alive",
34 34
         "Server": "gunicorn/19.9.0",
35
-        "Date": "Sun, 30 Dec 2018 17:30:29 GMT",
35
+        "Date": "Mon, 31 Dec 2018 09:40:32 GMT",
36 36
         "Content-Type": "text/html; charset=utf-8",
37 37
         "Access-Control-Allow-Origin": "*",
38 38
         "Access-Control-Allow-Credentials": "true",

+ 1
- 47
test/fixtures/vcr_cassettes/fetch_from_page.json
File diff suppressed because it is too large
View File


+ 1
- 46
test/fixtures/vcr_cassettes/page_is_empty.json View File

@@ -1,46 +1 @@
1
-[
2
-  {
3
-    "request": {
4
-      "body": "",
5
-      "headers": {
6
-        "user-agent": "Koype/0.0.1 (https://faq.koype.net/user-agent)"
7
-      },
8
-      "method": "get",
9
-      "options": {
10
-        "ssl_options": {
11
-          "server_name_indication": [
12
-            104,
13
-            116,
14
-            116,
15
-            112,
16
-            98,
17
-            105,
18
-            110,
19
-            46,
20
-            111,
21
-            114,
22
-            103
23
-          ]
24
-        }
25
-      },
26
-      "request_body": "",
27
-      "url": "https://httpbin.org/status/200"
28
-    },
29
-    "response": {
30
-      "binary": false,
31
-      "body": "",
32
-      "headers": {
33
-        "Connection": "keep-alive",
34
-        "Server": "gunicorn/19.9.0",
35
-        "Date": "Sun, 30 Dec 2018 17:30:27 GMT",
36
-        "Content-Type": "text/html; charset=utf-8",
37
-        "Access-Control-Allow-Origin": "*",
38
-        "Access-Control-Allow-Credentials": "true",
39
-        "Content-Length": "0",
40
-        "Via": "1.1 vegur"
41
-      },
42
-      "status_code": 200,
43
-      "type": "ok"
44
-    }
45
-  }
46
-]
1
+[]

+ 2
- 2
test/fixtures/vcr_cassettes/refresh_of_mf2_data.json View File

@@ -32,12 +32,12 @@
32 32
       "body": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <title>Quill</title>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <link rel=\"pingback\" href=\"https://webmention.io/aaronpk/xmlrpc\" />\n    <link rel=\"webmention\" href=\"https://webmention.io/aaronpk/webmention\" />\n\n    <!-- standard viewport tag to set the viewport to the device's width\n      , Android 2.3 devices need this so 100% width works properly and\n      doesn't allow children to blow up the viewport width-->\n    <meta name=\"viewport\" content=\"initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width\" />\n    <!-- width=device-width causes the iPhone 5 to letterbox the app, so\n      we want to exclude it for iPhone 5 to allow full screen apps -->\n    <meta name=\"viewport\" content=\"initial-scale=1.0,user-scalable=no,maximum-scale=1\" media=\"(device-height: 568px)\" />\n\n    <link rel=\"stylesheet\" href=\"/bootstrap/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\" href=\"/bootstrap/css/bootstrap-theme.min.css\">\n\n    <script src=\"/js/jquery-1.7.1.min.js\"></script>\n    <script src=\"/libs/localforage.js\"></script>\n\n    <script src=\"/bootstrap/js/bootstrap.min.js\"></script>\n    <script src=\"/libs/tokenfield/bootstrap-tokenfield.min.js\"></script>\n    <link rel=\"stylesheet\" href=\"/libs/tokenfield/bootstrap-tokenfield.min.css\">\n    <link rel=\"stylesheet\" href=\"/libs/tokenfield/tokenfield-typeahead.min.css\">\n\n    <link rel=\"stylesheet\" href=\"/css/style.css\">\n\n    <link rel=\"apple-touch-icon\" sizes=\"57x57\" href=\"/images/quill-icon-57.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"/images/quill-icon-72.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"/images/quill-icon-114.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"144x144\" href=\"/images/quill-icon-144.png\">\n    <link rel=\"apple-touch-icon\" sizes=\"196x196\" href=\"/images/quill-icon-196.png\">\n\n    <link rel=\"icon\" href=\"/favicon.ico\" type=\"image/x-icon\">\n    <link rel=\"icon\" sizes=\"196x196\" href=\"/images/quill-icon-196.png\">\n\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"theme-color\" content=\"#428bca\">\n\n    <link rel=\"manifest\" href=\"/js/manifest.json\">\n\n    <script src=\"/js/script.js\"></script>\n    <script src=\"/js/date.js\"></script>\n    <script src=\"/js/cassis.js\"></script>\n  </head>\n\n<body role=\"document\">\n<script type=\"text/javascript\">\n\n  var _gaq = _gaq || [];\n  _gaq.push(['_setAccount', '']);\n  _gaq.push(['_trackPageview']);\n\n  (function() {\n    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n  })();\n\n</script>\n\n<div class=\"page\">\n\n  <div class=\"container\">\n    <div class=\"narrow\">\n\n  <div class=\"jumbotron h-app h-x-app\">\n    <h1><img src=\"/images/quill-logo-144.png\" height=\"72\" style=\"margin-bottom: 13px;\" class=\"u-logo p-name\" alt=\"Quill\">Quill</h1>\n\n    <p class=\"tagline\">Quill is a simple app for posting text notes to your website.</p>\n\n          <p>To use Quill, sign in with your domain. Your website will need to support <a href=\"https://indieweb.org/micropub\">Micropub</a> for creating new posts.</p>\n\n      <form action=\"/auth/start\" method=\"get\" class=\"form-inline\">\n        <input type=\"url\" name=\"me\" placeholder=\"https://example.com\" value=\"\" class=\"form-control\" onchange=\"auto_prefix_url_field(this)\" autofocus>\n        <input type=\"submit\" value=\"Sign In\" class=\"btn btn-primary\">\n        <input type=\"hidden\" name=\"client_id\" value=\"https://quill.p3k.io/\">\n        <input type=\"hidden\" name=\"redirect_uri\" value=\"https://quill.p3k.io/auth/callback\">\n      </form>\n    \n    <a href=\"\" class=\"u-url\"></a>\n  </div>\n\n</div>\n  </div>\n\n  <div class=\"footer\">\n    <div class=\"nav\">\n      <ul class=\"nav navbar-nav\">\n\n        \n        <li><a href=\"/docs\">Docs</a></li>\n      </ul>\n      <ul class=\"nav navbar-nav navbar-right\">\n                  <li class=\"navbar-text\"></li>\n        \n      </ul>\n    </div>\n\n    <p class=\"credits\">&copy; 2018 by <a href=\"https://aaronparecki.com\">Aaron Parecki</a>.\n      This code is <a href=\"https://github.com/aaronpk/Quill\">open source</a>.\n      Feel free to send a pull request, or <a href=\"https://github.com/aaronpk/Quill/issues\">file an issue</a>.</p>\n  </div>\n</div>\n\n</body>\n</html>\n",
33 33
       "headers": {
34 34
         "Server": "nginx/1.14.0",
35
-        "Date": "Sun, 30 Dec 2018 17:30:31 GMT",
35
+        "Date": "Mon, 31 Dec 2018 09:40:40 GMT",
36 36
         "Content-Type": "text/html;charset=UTF-8",
37 37
         "Transfer-Encoding": "chunked",
38 38
         "Connection": "keep-alive",
39 39
         "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",
40
-        "Set-Cookie": "quill=v7s7dahs5luraue52d93ko9s37; expires=Tue, 29-Jan-2019 17:30:31 GMT; Max-Age=2592000; path=/",
40
+        "Set-Cookie": "quill=00k1fbgf4aqpib3k7loeuabjd5; expires=Wed, 30-Jan-2019 09:40:40 GMT; Max-Age=2592000; path=/",
41 41
         "Expires": "Thu, 19 Nov 1981 08:52:00 GMT",
42 42
         "Cache-Control": "no-store, no-cache, must-revalidate, post-check=0, pre-check=0",
43 43
         "Pragma": "no-cache"

+ 1
- 1
test/fixtures/vcr_cassettes/relme_failing_endpoint.json View File

@@ -32,7 +32,7 @@
32 32
       "headers": {
33 33
         "Connection": "keep-alive",
34 34
         "Server": "gunicorn/19.9.0",
35
-        "Date": "Sun, 30 Dec 2018 17:30:23 GMT",
35
+        "Date": "Mon, 31 Dec 2018 09:40:36 GMT",
36 36
         "Content-Type": "text/html; charset=utf-8",
37 37
         "Access-Control-Allow-Origin": "*",
38 38
         "Access-Control-Allow-Credentials": "true",

+ 1
- 1
test/fixtures/vcr_cassettes/relme_success.json View File

@@ -32,7 +32,7 @@
32 32
       "headers": {
33 33
         "Connection": "keep-alive",
34 34
         "Server": "gunicorn/19.9.0",
35
-        "Date": "Sun, 30 Dec 2018 17:30:22 GMT",
35
+        "Date": "Mon, 31 Dec 2018 09:40:37 GMT",
36 36
         "Content-Type": "text/html; charset=utf-8",
37 37
         "Access-Control-Allow-Origin": "*",
38 38
         "Access-Control-Allow-Credentials": "true",

+ 17
- 8
test/fixtures/vcr_cassettes/webmention_send_success.json View File

@@ -36,7 +36,7 @@
36 36
       "body": "",
37 37
       "headers": {
38 38
         "Server": "nginx/1.14.0",
39
-        "Date": "Sun, 30 Dec 2018 17:30:16 GMT",
39
+        "Date": "Mon, 31 Dec 2018 09:40:23 GMT",
40 40
         "Content-Type": "text/html; charset=UTF-8",
41 41
         "Connection": "keep-alive",
42 42
         "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",
@@ -50,9 +50,9 @@
50 50
   },
51 51
   {
52 52
     "request": {
53
-      "body": "%{source: \"http://a709dfde.ngrok.io/post/eius-laudantium-ea\", target: \"https://webmention.rocks/test/2\"}",
53
+      "body": "source=http%3A%2F%2F0a4ad5ab.ngrok.io%2Fpost%2Fassumenda-culpa-libero-provident-eaque&target=https%3A%2F%2Fwebmention.rocks%2Ftest%2F2",
54 54
       "headers": {
55
-        "user-agent": "Koype/0.0.1 (https://faq.koype.net/user-agent)"
55
+        "Content-Type": "application/x-www-form-urlencoded"
56 56
       },
57 57
       "method": "post",
58 58
       "options": {
@@ -81,11 +81,20 @@
81 81
       "url": "https://webmention.rocks/test/2/webmention?head=true"
82 82
     },
83 83
     "response": {
84
-      "binary": true,
85
-      "body": "g2wAAAACbQAAAARFWElUbAAAAAJtAAAAD2Z1bmN0aW9uX2NsYXVzZWwAAAAQaARkABVpYnJvd3NlX21lY2tfb3JpZ2luYWxkAAplbnN1cmVfYmlubAAAAAF0AAAAAmQABnNvdXJjZW0AAAAwaHR0cDovL2E3MDlkZmRlLm5ncm9rLmlvL3Bvc3QvZWl1cy1sYXVkYW50aXVtLWVhZAAGdGFyZ2V0bQAAAB9odHRwczovL3dlYm1lbnRpb24ucm9ja3MvdGVzdC8yamwAAAACaAJkAARmaWxlawAnL29wdC9rb3lwZS9kZXBzL2licm93c2Uvc3JjL2licm93c2UuZXJsaAJkAARsaW5lYgAAAhtqaARkABVpYnJvd3NlX21lY2tfb3JpZ2luYWxkAAtkb19zZW5kX3JlcWEHbAAAAAJoAmQABGZpbGVrACcvb3B0L2tveXBlL2RlcHMvaWJyb3dzZS9zcmMvaWJyb3dzZS5lcmxoAmQABGxpbmViAAAB7GpoBGQAFWlicm93c2VfbWVja19vcmlnaW5hbGQAE3RyeV9yb3V0aW5nX3JlcXVlc3RhDmwAAAACaAJkAARmaWxlawAnL29wdC9rb3lwZS9kZXBzL2licm93c2Uvc3JjL2licm93c2UuZXJsaAJkAARsaW5lYgAAAX9qaARkABRFbGl4aXIuRXhWQ1IuSGFuZGxlcmQAGGdldF9yZXNwb25zZV9mcm9tX3NlcnZlcmEDbAAAAAJoAmQABGZpbGVrABRsaWIvZXh2Y3IvaGFuZGxlci5leGgCZAAEbGluZWGOamgEZAANbWVja19jb2RlX2dlbmQABGV2YWxhBWwAAAACaAJkAARmaWxlawAqL29wdC9rb3lwZS9kZXBzL21lY2svc3JjL21lY2tfY29kZV9nZW4uZXJsaAJkAARsaW5lYcdqaARkABBFbGl4aXIuSFRUUG90aW9uZAAHcmVxdWVzdGEDbAAAAAJoAmQABGZpbGVrABBsaWIvaHR0cG90aW9uLmV4aAJkAARsaW5lYgAAAcVqaARkABFFbGl4aXIuS295cGUuSHR0cGQAEWRvX3JlcXVlc3RfcG90aW9uYQFsAAAAAmgCZAAEZmlsZWsAC2xpYi9odHRwLmV4aAJkAARsaW5lYUxqaARkABFFbGl4aXIuS295cGUuSHR0cGQAES1yZXF1ZXN0LzMtZnVuLTAtYQVsAAAAAmgCZAAEZmlsZWsAC2xpYi9odHRwLmV4aAJkAARsaW5lYS5qaARkABZFbGl4aXIuRW51bWVyYWJsZS5MaXN0ZAAGcmVkdWNlYQNsAAAAAmgCZAAEZmlsZWsAC2xpYi9lbnVtLmV4aAJkAARsaW5lYgAADLNqaARkAAtFbGl4aXIuRW51bWQADHJlZHVjZV93aGlsZWEDbAAAAAJoAmQABGZpbGVrAAtsaWIvZW51bS5leGgCZAAEbGluZWIAAAeWamgEZAAaRWxpeGlyLkluZGllV2ViLldlYm1lbnRpb25kAAdkb19zZW5kYQJsAAAAAmgCZAAEZmlsZWsAGmxpYi9pbmRpZXdlYi93ZWJtZW50aW9uLmV4aAJkAARsaW5lYaJqaARkABpFbGl4aXIuSW5kaWVXZWIuV2VibWVudGlvbmQABHNlbmRhAWwAAAACaAJkAARmaWxlawAabGliL2luZGlld2ViL3dlYm1lbnRpb24uZXhoAmQABGxpbmVhMmpoBGQAHkVsaXhpci5JbmRpZVdlYi5XZWJtZW50aW9uVGVzdGQAKnRlc3QgLnNlbmQvMSBzZW5kcyBXZWJtZW50aW9uIHN1Y2Nlc3NmdWxseWEBbAAAAAJoAmQABGZpbGVrACZ0ZXN0L3VuaXQvaW5kaWV3ZWIvd2VibWVudGlvbl90ZXN0LmV4c2gCZAAEbGluZWFHamgEZAAURWxpeGlyLkV4VW5pdC5SdW5uZXJkAAlleGVjX3Rlc3RhAWwAAAACaAJkAARmaWxlawAVbGliL2V4X3VuaXQvcnVubmVyLmV4aAJkAARsaW5lYgAAATJqaARkAAV0aW1lcmQAAnRjYQFsAAAAAmgCZAAEZmlsZWsACXRpbWVyLmVybGgCZAAEbGluZWGmamgEZAAURWxpeGlyLkV4VW5pdC5SdW5uZXJkABQtc3Bhd25fdGVzdC8zLWZ1bi0xLWEEbAAAAAJoAmQABGZpbGVrABVsaWIvZXhfdW5pdC9ydW5uZXIuZXhoAmQABGxpbmVh9Wpqamo=",
86
-      "headers": [],
87
-      "status_code": null,
88
-      "type": "error"
84
+      "binary": false,
85
+      "body": "no_link_found\n\nThe source document does not contain a link to the target URL.\n\nThe source URL returned an HTTP 404 response.\n\nThe source document must contain an <a> tag with an href attribute matching the target URL specified.\n",
86
+      "headers": {
87
+        "Server": "nginx/1.14.0",
88
+        "Date": "Mon, 31 Dec 2018 09:40:24 GMT",
89
+        "Content-Type": "text/plain;charset=UTF-8",
90
+        "Transfer-Encoding": "chunked",
91
+        "Connection": "keep-alive",
92
+        "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",
93
+        "Access-Control-Allow-Origin": "*",
94
+        "Access-Control-Allow-Methods": "GET, POST"
95
+      },
96
+      "status_code": 400,
97
+      "type": "ok"
89 98
     }
90 99
   }
91 100
 ]

+ 0
- 51
test/fixtures/vcr_cassettes/webmention_test_for_headers.json View File

@@ -1,51 +0,0 @@
1
-[
2
-  {
3
-    "request": {
4
-      "body": "",
5
-      "headers": {
6
-        "user-agent": "Koype/0.0.1 (https://faq.koype.net/user-agent)"
7
-      },
8
-      "method": "head",
9
-      "options": {
10
-        "ssl_options": {
11
-          "server_name_indication": [
12
-            119,
13
-            101,
14
-            98,
15
-            109,
16
-            101,
17
-            110,
18
-            116,
19
-            105,
20
-            111,
21
-            110,
22
-            46,
23
-            114,
24
-            111,
25
-            99,
26
-            107,
27
-            115
28
-          ]
29
-        }
30
-      },
31
-      "request_body": "",
32
-      "url": "https://webmention.rocks/test/2"
33
-    },
34
-    "response": {
35
-      "binary": false,
36
-      "body": "",
37
-      "headers": {
38
-        "Server": "nginx/1.14.0",
39
-        "Date": "Sun, 30 Dec 2018 17:30:17 GMT",
40
-        "Content-Type": "text/html; charset=UTF-8",
41
-        "Connection": "keep-alive",
42
-        "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",
43
-        "Link": "<https://webmention.rocks/test/2/webmention?head=true>; rel=webmention",
44
-        "Access-Control-Allow-Origin": "*",
45
-        "Access-Control-Allow-Methods": "GET, POST"
46
-      },
47
-      "status_code": 200,
48
-      "type": "ok"
49
-    }
50
-  }
51
-]

+ 1
- 1
test/fixtures/vcr_cassettes/webmention_test_for_headers_1.json View File

@@ -36,7 +36,7 @@
36 36
       "body": "",
37 37
       "headers": {
38 38
         "Server": "nginx/1.14.0",
39
-        "Date": "Sun, 30 Dec 2018 20:50:56 GMT",
39
+        "Date": "Mon, 31 Dec 2018 09:40:26 GMT",
40 40
         "Content-Type": "text/html; charset=UTF-8",
41 41
         "Connection": "keep-alive",
42 42
         "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",

+ 1
- 1
test/fixtures/vcr_cassettes/webmention_test_for_headers_2.json View File

@@ -36,7 +36,7 @@
36 36
       "body": "",
37 37
       "headers": {
38 38
         "Server": "nginx/1.14.0",
39
-        "Date": "Sun, 30 Dec 2018 20:57:00 GMT",
39
+        "Date": "Mon, 31 Dec 2018 09:40:27 GMT",
40 40
         "Content-Type": "text/html; charset=UTF-8",
41 41
         "Connection": "keep-alive",
42 42
         "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",

+ 1
- 1
test/fixtures/vcr_cassettes/webmention_test_for_headers_3.json View File

@@ -36,7 +36,7 @@
36 36
       "body": "",
37 37
       "headers": {
38 38
         "Server": "nginx/1.14.0",
39
-        "Date": "Sun, 30 Dec 2018 21:38:56 GMT",
39
+        "Date": "Mon, 31 Dec 2018 09:40:27 GMT",
40 40
         "Content-Type": "text/html; charset=UTF-8",
41 41
         "Connection": "keep-alive",
42 42
         "X-Powered-By": "PHP/5.6.36-1+ubuntu16.04.1+deb.sury.org+1",

+ 1
- 50
test/fixtures/vcr_cassettes/webmention_test_for_headers_4.json
File diff suppressed because it is too large
View File


+ 2
- 2
test/integration/views/error_view_test.exs View File

@@ -5,10 +5,10 @@ defmodule Koype.Web.ErrorViewTest do
5 5
   import Phoenix.View, only: [render_to_string: 3]
6 6
 
7 7
   test "renders 404.html" do
8
-    assert render_to_string(Koype.Web.ErrorView, "404.html", conn: build_conn()) == "Not Found"
8
+    assert render_to_string(Koype.Web.ErrorView, "404.html", conn: build_conn()) =~ "Not Found"
9 9
   end
10 10
 
11 11
   test "renders 500.html" do
12
-    assert render_to_string(Koype.Web.ErrorView, "500.html", conn: build_conn()) == "Internal Server Error"
12
+    assert render_to_string(Koype.Web.ErrorView, "500.html", conn: build_conn()) =~ "server error"
13 13
   end
14 14
 end

+ 14
- 14
test/unit/indieweb/micropub/entry_test.exs View File

@@ -327,20 +327,20 @@ defmodule IndieWeb.Micropub.EntryTest do
327 327
         find: fn ^entry -> {:ok, entry_json} end
328 328
       ) do
329 329
         assert {:ok, state: :updated, model: _} =
330
-                 Subject.invoke(
331
-                   "update",
332
-                   scope: ~w(update),
333
-                   params: [
334
-                     reserved: %{
335
-                       "url" => url,
336
-                       "add" => %{
337
-                         "koype" => ["wheel"],
338
-                         "content" => ["wheel"]
339
-                       }
340
-                     },
341
-                     content: %{}
342
-                   ]
343
-                 )
330
+          Subject.invoke(
331
+            "update",
332
+            scope: ~w(update),
333
+            params: [
334
+              reserved: %{
335
+                "url" => url,
336
+                "add" => %{
337
+                  "koype" => ["wheel"],
338
+                  "content" => ["wheel"]
339
+                }
340
+              },
341
+              content: %{}
342
+            ]
343
+          )
344 344
 
345 345
         assert called(Model.Json.find(entry))
346 346
         assert called(Model.Json.persist(entry, :_))

+ 2
- 1
test/unit/timeline_test.exs View File

@@ -6,7 +6,8 @@ defmodule Koype.TimelineTest do
6 6
   describe ".entries/0" do
7 7
     test "provides list of entries in correct order" do
8 8
       entries = insert_list(25, :entry)
9
-      expected_list = Enum.sort(entries, &(&1.inserted_at >= &2.inserted_at)) |> Enum.take(10)
9
+      expected_list = Enum.sort(entries, &(&1.inserted_at >= &2.inserted_at)) |> Enum.take(10) |> Enum.map(fn e -> e.id end)
10
+      resulting_list = Subject.entries() |> Enum.map(fn e -> e.id end)
10 11
       assert expected_list == Subject.entries()
11 12
     end
12 13
   end

+ 12
- 0
web/controllers/entry_controller.ex View File

@@ -33,4 +33,16 @@ defmodule Koype.Web.EntryController do
33 33
         |> render("view-notfound.html")
34 34
     end
35 35
   end
36
+
37
+  def stream(conn, params \\ %{"type" => nil}) do
38
+     results = Koype.Timeline.entries(params)
39
+
40
+      if results.total_entries == 0 do
41
+        render(conn, :"stream-empty", type: params["type"])
42
+      else
43
+        conn
44
+        |> Scrivener.Headers.paginate(results)
45
+        |> render(:stream, paginator: results, type: params["type"])
46
+      end
47
+  end
36 48
 end

+ 5
- 4
web/controllers/fallback_controller.ex View File

@@ -1,6 +1,7 @@
1 1
 defmodule Koype.Web.FallbackController do
2 2
   use Phoenix.Controller
3 3
 
4
+  def call(conn, args \\ :catch_all)
4 5
   def call(conn, {:error, :not_found}) do
5 6
     conn
6 7
     |> put_status(:not_found)
@@ -9,10 +10,6 @@ defmodule Koype.Web.FallbackController do
9 10
     |> render(:"404")
10 11
   end
11 12
 
12
-  def call(conn, :catch_all) do
13
-    call(conn, {:error, :not_found})
14
-  end
15
-
16 13
   def call(conn, {:error, :internal_server_error}) do
17 14
     conn
18 15
     |> put_status(:internal_server_error)
@@ -20,4 +17,8 @@ defmodule Koype.Web.FallbackController do
20 17
     |> put_layout({Koype.Web.LayoutView, "simple.html"})
21 18
     |> render(:"500")
22 19
   end
20
+
21
+  def call(conn, :catch_all) do
22
+    call(conn, {:error, :not_found})
23
+  end
23 24
 end

+ 3
- 9
web/controllers/page_controller.ex View File

@@ -1,20 +1,14 @@
1 1
 defmodule Koype.Web.PageController do
2 2
   use Koype.Web, :controller
3 3
 
4
-  def index(conn, params) do
4
+  def index(conn, _params) do
5 5
     if !Koype.Setup.complete?() do
6 6
       conn
7 7
       |> put_flash(:info, "Hey there! Let's finish setting up your site.")
8 8
       |> redirect(to: "/setup")
9 9
     else
10
-      results = Koype.Timeline.entries(params)
11
-
12
-      if results.page_size == 0 do
13
-        render(conn, :"stream-empty")
14
-      else
15
-        render(conn, :stream, paginator: results)
16
-      end
17
-    end
10
+      redirect(conn, to: "/stream")
11
+     end
18 12
   end
19 13
 
20 14
   def mf2(conn, params)

+ 1
- 1
web/endpoint.ex View File

@@ -9,7 +9,7 @@ defmodule Koype.Web.Endpoint do
9 9
     at: "/",
10 10
     from: :koype,
11 11
     gzip: true,
12
-    only: ~w(assets images favicon.ico robots.txt)
12
+    only: ~w(assets)
13 13
   )
14 14
 
15 15
   if code_reloading? do

+ 0
- 1
web/router.ex View File

@@ -36,7 +36,6 @@ defmodule Koype.Web.Router do
36 36
 
37 37
     get("/stream", EntryController, :stream)
38 38
     get("/post/:id", EntryController, :view)
39
-    get("/post/of-type/:type", EntryController, :view_by_type)
40 39
 
41 40
     get("/categories", CategoryController, :index)
42 41
     get("/category/:id", CategoryController, :view)

+ 15
- 44
web/static/css/koype.scss View File

@@ -4,56 +4,27 @@
4 4
   --font-family-sans: "Source Sans Pro";
5 5
   --font-family-serif: "Source Serif Pro";
6 6
   --font-family-mono: "Source Code Pro";
7
-  --animation-speed: 0.15s;
8
-  --animation-type: ease-in;
9
-  --navy: #001b44;
10
-}
11
-
12
-.e-content {
13
-  p {
14
-    margin: 0rem auto;
15
-    text-align: justify;
16
-    text-align-last: left;
17
-
18
-    &:first-child {
19
-      font-size: 120%;
20
-    }
21
-
22
-    &:first-child::first-line {
23
-      font-size: 140%;
24
-    }
25
-  }
26
-
27
-  pre {
28
-    background-color: var(--black);
29
-    color: var(--green);
30
-    padding: 1.5rem 0rem;
31
-    line-height: 1;
32
-  }
33 7
 }
34 8
 
35 9
 html.wf-active {
36
-  h1, h2, h3, h4, h5, h6, p
37
-  blockquote, .sans-serif {
38
-    font-family: var(--font-family-sans), sans-serif;
39
-  }
40
-
41
-  input, button, form,
42
-  article, aside,
43
-  main, footer, header, .serif {
44
-    font-family: var(--font-family-serif), serif;
10
+  &.wf-sourceserifpro-n4-active {
11
+    h1, h2, h3, h4, h5, h6,
12
+    cite, blockquote, .sans-serif {
13
+      font-family: var(--font-family-serif), sans-serif;
14
+    }
45 15
   }
46 16
 
47
-  pre, code, kbd, .code {
48
-    font-family: var(--font-family-mono), monospace;
17
+  &.wf-sourcesanspro-n4-active {
18
+    input, button, form,
19
+    article, aside, li,
20
+    main, footer, header, p, .serif {
21
+      font-family: var(--font-family-sans), serif;
22
+    }
49 23
   }
50
-}
51 24
 
52
-a {
53
-  transition: color var(--animation-speed) var(--animation-style), text-decoration var(--animation-speed) var(--animation-style);
54
-  text-decoration: none;
55
-
56
-  &:hover {
57
-    text-decoration: dotted;
25
+  &.wf-sourcecodepro-n4-active {
26
+    pre, code, kbd, .code {
27
+      font-family: var(--font-family-mono), monospace;
28
+    }
58 29
   }
59 30
 }

+ 1
- 1
web/static/css/vendor.scss View File

@@ -2,4 +2,4 @@
2 2
 @import "pretty-checkbox/src/pretty-checkbox";
3 3
 @import "quill/dist/quill.core.css";
4 4
 @import "quill/dist/quill.bubble.css";
5
-@import url("leaflet/dist/leaflet.css");
5
+// TODO: Import leaflet.

+ 1
- 0
web/static/images/background-wiggle.svg View File

@@ -0,0 +1 @@
1
+<svg width="52" height="26" viewBox="0 0 52 26" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="#000"><path d="M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z" /></g></g></svg>

+ 1
- 1
web/templates/entry/_sparkline.html.eex View File

@@ -22,7 +22,7 @@
22 22
     <% end %>
23 23
     </li>
24 24
     <li class="lh-copy mt1">
25
-      <a class="link dim fw5 color-inherit" href="<%= entry_path(@conn, :view_by_type, determine_type(@model)) %>">
25
+      <a class="link dim fw5 color-inherit" href="<%= entry_path(@conn, :stream, type: @model.type) %>">
26 26
         a
27 27
         <i class="v-mid pv1 h1 w1" data-feather="<%= icon_for_entry(@model) %>"></i>
28 28
         <%= determine_type(@model) %>

+ 0
- 13
web/templates/entry/index.html.eex View File

@@ -1,13 +0,0 @@
1
-<section class="mw7 w-two-thirds center pa2">
2
-  <h2 class="f2 lh-title">Entries</h2>
3
-  <%= for entry <- @entries do %>
4
-  <section>
5
-    <p class="lh-copy">
6
-      <a title="<%= friendly_type_name(entry.model) %>" class="link" href="<%= Entry.get_uri(entry.model) %>">
7
-        <i class="near-black h2 w2 v-mid" data-feather="<%= icon_for_entry(entry.model) %>"></i>
8
-        <%= determine_title(entry.model) %>
9
-      </a>
10
-    </p>
11
-  </section>
12
-  <% end %>
13
-</section>

+ 4
- 0
web/templates/entry/stream-empty.html.eex View File

@@ -0,0 +1,4 @@
1
+<section class="mw7 pa2 center">
2
+  <h1 class="f3 lh-title gray">No Content Found</h1>
3
+  <p class="lh-copy f5 near-black">You haven't made a single post on your site yet!</p>
4
+</section>

+ 53
- 0
web/templates/entry/stream.html.eex View File

@@ -0,0 +1,53 @@
1
+<article class="w-100 mw7 center pl4 pr1 h-feed">
2
+  <% [first, last] = [List.first(@paginator.entries), List.last(@paginator.entries)] %>
3
+  <%= if first != last do %>
4
+    <p class="lh-copy f5 gray">
5
+      A snippet of a stream showing posts from <time datetime="<%= first.inserted_at %>"><%= humanize_date(first.inserted_at) %></time>
6
+      to <time datetime="<%= last.inserted_at %>"><%= humanize_date(last.inserted_at) %></time>; <%= distance_of_time_in_words(last.inserted_at, first.inserted_at) %>.
7
+    </p>
8
+  <% end %>
9
+  <%= if @paginator.page_number > 1 do %>
10
+    <nav class="w-100 bl bw1 b--silver pa3 tc flex flex-row justify-between items-center">
11
+      <%= if @paginator.page_number > 0 do %>
12
+        <a href="<%= entry_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "1")) - 1}) %>" rel="previous" class="ttu navy dim link">Previous</a>
13
+      <% end %>
14
+      <span>
15
+        page <strong><%= @paginator.page_number %></strong> of <strong><%= @paginator.total_pages %></strong>
16
+      </span>
17
+      <%= if @paginator.page_number != @paginator.total_pages do %>
18
+        <a href="<%= entry_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "0")) + 1}) %>" rel="next" class="ttu navy dim link">Next</a>
19
+      <% end %>
20
+    </nav>
21
+  <% end %>
22
+  <%= for entry <- @paginator.entries do %>
23
+    <% color = Koype.Web.EntryView.color_for_type(entry.type) %>
24
+    <section data-post-type="<%= entry.type %>" data-post-id="<%= entry.id %>" class="flex flex-row flex-wrap h-entry w-100 bl bw1 b--silver pa2 items-center">
25
+      <span title="<%= entry.name %>" class="self-center relative right-2 ml1 b--silver f1 v-mid fw7 br-100 bw1 ba1 b--solid b--<%= color.foreground %> w1 h1 pa2 white bg-<%= color.background %>">
26
+        <i class="h1 w1 center db v-mid <%= color.foreground %> " data-feather="<%= Koype.Web.EntryView.icon_for_type(entry.type) %>"></i>
27
+      </span>
28
+      <div class="flex flex-row flex-wrap items-start justify-around w-100 mw6 relative left--1">
29
+        <div class="flex-auto flex-grow self-start order-1 w-100">
30
+          <%= render_entry_inline(entry) %>
31
+        </div>
32
+        <aside class="flex-grow flex-auto gray pa2 lh-copy order-2 self-end">
33
+          <span class="f5 fw7 v-mid"><%= entry.name %></span>
34
+          &bull;
35
+          <time class="f6 v-mid ttu" datetime="<%= entry.inserted_at %>"><%= Koype.Web.EntryView.humanize_date(entry.inserted_at) %></time>
36
+          <a href="<%= Koype.Repo.Entry.get_uri(entry) %>" class="u-url u-uid f6 fw6 blue dim">
37
+            <i class="h1 w1 v-mid navy" data-feather="link">Permalink</i>
38
+          </a>
39
+        </aside>
40
+      </div>
41
+    </section>
42
+  <% end %>
43
+  <%= if @paginator.page_number != @paginator.total_pages do %>
44
+    <nav class="w-100 bl bw1 b--silver pa3 tc flex flex-row justify-between items-center">
45
+      <%= if @paginator.page_number > 1 do %>
46
+        <a href="<%= entry_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "1")) - 1}) %>" rel="previous" class="ttu navy dim link">Previous</a>
47
+      <% end %>
48
+      <%= if @paginator.page_number != @paginator.total_pages do %>
49
+        <a href="<%= entry_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "1")) + 1}) %>" rel="next" class="ttu navy dim link">Next</a>
50
+      <% end %>
51
+    </nav>
52
+  <% end %>
53
+</article>

web/templates/page/stream_inline-contextual.html.eex → web/templates/entry/stream_inline-contextual.html.eex View File


web/templates/page/stream_inline-media.html.eex → web/templates/entry/stream_inline-media.html.eex View File


web/templates/page/stream_inline-single.html.eex → web/templates/entry/stream_inline-single.html.eex View File


+ 1
- 1
web/templates/error/500.html.eex View File

@@ -2,7 +2,7 @@
2 2
   <h1 class="h2 dark-gray lh-title mt1 measure">Bleep Bloop BLE&mdash;</h1>
3 3
   <p class="lh-copy gray f4 measure">
4 4
     Something went wrong with that action. Don't worry; it was the site. The site's fine!
5
-    I think?
5
+    I think? It was definitely a server error.
6 6
   </p>
7 7
   <p class="lh-copy gray f5 measure-narrow">Go to the <a href="<%= page_path(@conn, :index) %>" class="link underline blue">home page</a>.</p>
8 8
 </section>

+ 6
- 4
web/templates/layout/app.html.eex View File

@@ -8,6 +8,10 @@
8 8
     <meta name="<%= name %>" content="<%= @view_module.tag({:meta, name}, @view_template, assigns) %>" />
9 9
     <% end %>
10 10
     <title><%= @view_module.title(@view_template, assigns) %> - <%= base_title() %></title>
11
+    <link rel="icon" type="image/png" href="<%= static_path(@conn, "/assets/images/favicon.png") %>" sizes="100x100" />
12
+    <link rel="icon" type="image/x-icon" href="<%= static_path(@conn, "/assets/images/favicon.png") %>" />
13
+    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/vendor.css") %>" />
14
+    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/koype.css") %>" />
11 15
     <%= for name <- Koype.Web.tags(:link) ++ @view_module.tags(:link, @view_template, assigns) do %>
12 16
       <% href = @view_module.tag({:link, name}, @view_template, assigns) %>
13 17
       <%= cond do %>
@@ -17,12 +21,10 @@
17 21
     <link rel="<%= name %>" href="<%= href %>" /><% true -> %>
18 22
       <% end %>
19 23
     <% end %>
20
-    <link rel="icon" type="image/png" href="<%= static_path(@conn, "/images/favicon.png") %>" sizes="100x100" />
21
-    <link rel="icon" type="image/x-icon" href="<%= static_path(@conn, "/images/favicon.png") %>" />
22
-    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/vendor.css") %>" />
23
-    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/koype.css") %>" />
24 24
   </head>
25 25
   <body class="w-100 min-h-100 min-vh-100 flex flex-column near-black bg-near-white sans-serif">
26
+    <script async defer type="text/javascript" src="<%= static_path(@conn, "/assets/css/vendor.js") %>"></script>
27
+    <script async defer type="text/javascript" src="<%= static_path(@conn, "/assets/css/koype.js") %>"></script>
26 28
     <%= render Koype.Web.PageView, "_header.html", assigns %>
27 29
     <main role="main" class="flex flex-auto flex-grow self-stretch content-stretch flex-column cb cf order-2 items-start self-start">
28 30
       <%= render Koype.Web.PageView, "_flash.html", assigns %>

+ 4
- 4
web/templates/layout/simple.html.eex View File

@@ -5,10 +5,10 @@
5 5
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 6
     <meta name="viewport" content="initial-scale=1.0,user-scalable=yes,width=device-width,height=device-height" />
7 7
     <title><%= @view_module.title(@view_template, assigns) %> - Koype</title>
8
-    <link rel="icon" type="image/png" href="<%= static_path(@conn, "/images/favicon.png") %>" sizes="100x100" />
9
-    <link rel="icon" type="image/x-icon" href="<%= static_path(@conn, "/images/favicon.png") %>" />
10
-    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/vendor.css") %>" />
11
-    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/css/koype.css") %>" />
8
+    <link rel="icon" type="image/png" href="<%= static_path(@conn, "/assets/favicon.png") %>" sizes="100x100" />
9
+    <link rel="icon" type="image/x-icon" href="<%= static_path(@conn, "/assets/favicon.png") %>" />
10
+    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/vendor.css") %>" />
11
+    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/koype.css") %>" />
12 12
   </head>
13 13
   <body class="w-100 min-h-100 min-vh-100 flex flex-column near-black bg-near-white sans-serif">
14 14
     <main role="main" class="flex flex-auto flex-grow self-stretch content-stretch flex-column cb cf order-2 items-start self-start">

+ 19
- 28
web/templates/page/_footer.html.eex View File

@@ -1,11 +1,11 @@
1
-<footer role="main" class="w-100 pa2 bg-navy bg-navy-gradient lightest-blue cb cf order-4 items-center sans-serif">
1
+<footer role="main" class="w-100 pa2 bg-near-black silver order-4 items-center sans-serif">
2 2
   <div class="mw8 flex flex-column flex-row-l justify-around center">
3 3
     <%= if Koype.Profile.complete? do %>
4 4
       <div class="h-card pa2 items-center flex flex-column flex-row-l flex-auto flex-grow items-start">
5
-        <a href="<%= Koype.host %>" rel="author me authn" class="u-url db pa2 link lightest-blue">
5
+        <a href="<%= Koype.host %>" rel="author me authn" class="u-url db pa2 link light-gray">
6 6
           <%= if Koype.Profile.photo do %>
7 7
             <img alt="<%= Koype.Profile.displayed_name %>"
8
-                class="center mw4 ba bw1 b--white-20 bg--near-white br-100 w-auto u-photo db"
8
+                class="center mw5 ba bw1 b--moon-gray-20 bg--moon-gray-20 br-100 w-auto u-photo db"
9 9
                 style="max-height: 4rem"
10 10
                 src="<%= Koype.Profile.photo %>" />
11 11
           <% end %>
@@ -13,45 +13,36 @@
13 13
         </a>
14 14
         <small class="db f5 self-center-l flex-grow flex-auto dib-ns ml2-l v-mid lh-copy tj tc-l p-note measure-narrow"><%= Koype.Profile.note %></small>
15 15
       </div>
16
-      <ul class="list pa2 mw5 f6 center flex flex-auto flex-row dn w-50 w-third-l flex-wrap justify-center mh2-l br-l bl-l bw1-l b--white-20">
17
-        <% for %{type: type, names: name} <- IndieWeb.Post.known_types do %>
18
-          <li class="lh-copy mv1 w-auto tc">
19
-            <a title="<%= name %>" class="flex justify-center items-center w2 h1 grow animate br-100 dib link lightest-blue" href="<%= entry_path(@conn, :view_by_type, type) %>">
20
-              <i role="none" class="h1 w1 mb1 mr1 v-mid" data-feather="<%= Koype.Web.EntryView.icon_for_type(type) %>"></i>
21
-            </a>
22
-          </li>
23
-        <% end %>
24
-      </ul>
25
-      <ul class="list pa2 f6 center w-50 w-auto-l">
16
+      <ul class="list pv2 ph4 f6 center measure-wide">
26 17
         <li class="lh-copy mb1">
27
-          <a href="<%= Koype.host %>" class="white dim link">
28
-            <i class="near-white h1 w1 pa1 v-mid" data-feather="home"></i>
29
-            <span class="v-mid">Home</span>
18
+          <a href="<%= Koype.host %>" class="moon-gray link">
19
+            <i class="hover-orange h1 w1 pa1 v-mid" data-feather="home"></i>
20
+            <span class="v-mid underline-hover">Home</span>
30 21
           </a>
31 22
         </li>
32 23
         <%= if is_signed_in?(@conn, :owner) do %>
33 24
           <li class="lh-copy mb1">
34
-            <a href="<%= settings_path(@conn, :view) %>" class="white dim link">
35
-              <i class="moon-gray h1 w1 pa1 v-mid" data-feather="settings"></i>
36
-              <span class="v-mid">Settings</span>
25
+            <a href="<%= settings_path(@conn, :view) %>" class="moon-gray link">
26
+              <i class="h1 w1 pa1 v-mid" data-feather="settings"></i>
27
+              <span class="v-mid underline-hover">Settings</span>
37 28
             </a>
38 29
           </li>
39 30
           <li class="lh-copy mb1">
40
-            <a href="https://quill.p3k.io/?me=<%= Koype.host %>&dontask=1" class="white dim link">
41
-              <i class="light-blue h1 w1 pa1 v-mid" data-feather="edit"></i>
42
-              <span class="v-mid">Compose</span>
31
+            <a href="https://quill.p3k.io/?me=<%= Koype.host %>&dontask=1" class="moon-gray link">
32
+              <i class="h1 w1 pa1 v-mid" data-feather="edit"></i>
33
+              <span class="v-mid underline-hover">Compose</span>
43 34
             </a>
44 35
           </li>
45 36
           <li class="lh-copy mb1">
46
-            <a href="<%= rel_me_path(@conn, :view) %>" class="white dim link">
47
-              <i class="green h1 w1 pa1 v-mid" data-feather="check-circle"></i>
48
-              <span class="v-mid">Verified Links</span>
37
+            <a href="<%= rel_me_path(@conn, :view) %>" class="moon-gray link">
38
+              <i class="h1 w1 pa1 v-mid" data-feather="check-circle"></i>
39
+              <span class="v-mid underline-hover">Verified Links</span>
49 40
             </a>
50 41
           </li>
51 42
           <li class="lh-copy">
52
-            <a href="<%= webmention_path(@conn, :index) %>" class="white dim link">
53
-              <i class="light-blue h1 w1 pa1 v-mid" data-feather="globe"></i>
54
-              <span class="v-mid">Webmentions</span>
43
+            <a href="<%= webmention_path(@conn, :index) %>" class="moon-gray link">
44
+              <i class="h1 w1 pa1 v-mid" data-feather="globe"></i>
45
+              <span class="v-mid underline-hover">Webmentions</span>
55 46
             </a>
56 47
           </li>
57 48
         <% end %>

+ 4
- 4
web/templates/page/_header.html.eex View File

@@ -1,23 +1,23 @@
1
-<header role="main" class="mw7 w-100 order-1 flex flex-row flex-wrap pa2 mt2-l justify-end items-center self-center">
1
+<header role="main" class="mw7 w-100 order-1 flex flex-row flex-wrap pa2 mt2-l justify-end items-center self-center gray">
2 2
   <a class="ma1 link pv1 ph2 dim underline-hover near-black grow br3" href="<%= page_path(@conn, :index) %>">
3 3
     <i class="h1 w-auto v-mid" data-feather="home"></i>
4 4
     Home
5 5
   </a>
6 6
   <%= if is_signed_in?(@conn, :owner) do %>
7 7
     &bull;
8
-    <a role="presentation" class="link v-mid ma1 dim pv1 ph2 underline-hover navy dim grow br3 white-80" href="<%= settings_path(@conn, :view) %>">
8
+    <a role="presentation" class="link v-mid ma1 dim pv1 ph2 underline-hover near-black dim grow br3 white-80" href="<%= settings_path(@conn, :view) %>">
9 9
       <i class="h1 w-auto v-mid" data-feather="settings"> </i>
10 10
       <span class="v-mid">Settings</span>
11 11
     </a>
12 12
     &bull;
13
-    <a role="presentation" class="link ma1 dim pv1 underline-hover ph2 gray dim grow br3" href="<%= auth_path(@conn, :logout, redirect_to: Base.url_encode64(Phoenix.Controller.current_path(@conn))) %>">
13
+    <a role="presentation" class="link ma1 dim pv1 underline-hover ph2 silver dim grow br3" href="<%= auth_path(@conn, :logout, redirect_to: Base.url_encode64(Phoenix.Controller.current_path(@conn))) %>">
14 14
       <i class="h1 w-auto v-mid" data-feather="log-out"> </i>
15 15
       Log Out
16 16
     </a>
17 17
   <% end %>
18 18
   <%= if is_signed_out?(@conn, :owner) do %>
19 19
     &bull;
20
-    <a role="presentation" class="link dim pv1 ph2 underline-hover dark-green dim grow br3" href="<%= auth_path(@conn, :new, redirect_to: Base.url_encode64(Phoenix.Controller.current_path(@conn))) %>">
20
+    <a role="presentation" class="link dim pv1 ph2 underline-hover mid-gray dim grow br3" href="<%= auth_path(@conn, :new, redirect_to: Base.url_encode64(Phoenix.Controller.current_path(@conn))) %>">
21 21
       <i class="h1 w-auto v-mid" data-feather="log-in"> </i>
22 22
       Log In
23 23
     </a>

+ 0
- 4
web/templates/page/stream-empty.html.eex View File

@@ -1,4 +0,0 @@
1
-<%= if is_signed_in?(@conn, :owner) do %>
2
-
3
-<%= else %>
4
-<% end %>

+ 0
- 44
web/templates/page/stream.html.eex View File

@@ -1,44 +0,0 @@
1
-<article class="w-100 mw7 center pl4 pr1 h-feed">
2
-  <%= if @paginator.page_number > 1 do %>
3
-  <nav class="w-100 bl bw1 b--silver pa3 tc flex flex-row justify-between items-center">
4
-    <%= if @paginator.page_number > 0 do %>
5
-    <a href="<%= page_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "1")) - 1}) %>" rel="previous" class="ttu navy dim link">Previous</a>
6
-    <% end %>
7
-    <span>
8
-      page <strong><%= @paginator.page_number %></strong> of <strong><%= @paginator.total_pages %></strong>
9
-    </span>
10
-    <%= if @paginator.page_number != @paginator.total_pages do %>
11
-      <a href="<%= page_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "0")) + 1}) %>" rel="next" class="ttu navy dim link">Next</a>
12
-    <% end %>
13
-  </nav>
14
-  <% end %>
15
-  <%= for entry <- @paginator.entries do %>
16
-  <% color = Koype.Web.EntryView.color_for_type(entry.type) %>
17
-  <section data-post-type="<%= entry.type %>" data-post-id="<%= entry.id %>" class="flex flex-row flex-wrap h-entry w-100 bl bw1 b--silver pa2 items-center">
18
-    <span title="<%= entry.name %>" class="self-center relative right-2 ml1 b--silver f1 v-mid fw7 br-100 bw1 ba1 b--solid b--<%= color.foreground %> w1 h1 pa2 white bg-<%= color.background %>">
19
-      <i class="h1 w1 center db v-mid <%= color.foreground %> " data-feather="<%= Koype.Web.EntryView.icon_for_type(entry.type) %>"></i>
20
-    </span>
21
-    <div class="flex flex-row flex-wrap items-start justify-around w-100 mw6 relative left--1">
22
-      <div class="flex-auto flex-grow self-start order-1 w-100">
23
-        <%= render_entry_inline(entry) %>
24
-      </div>
25
-      <aside class="flex-grow flex-auto gray pa2 lh-copy order-2 self-end">
26
-        <span class="f5 fw7 v-mid"><%= entry.name %></span>
27
-        &bull;
28
-        <time class="f6 v-mid ttu" datetime="<%= entry.inserted_at %>"><%= Koype.Web.EntryView.humanize_date(entry.inserted_at) %></time>
29
-        <a href="<%= Koype.Repo.Entry.get_uri(entry) %>" class="u-url u-uid f6 fw6 blue dim">
30
-          <i class="h1 w1 v-mid navy" data-feather="link">Permalink</i>
31
-        </a>
32
-      </aside>
33
-    </div>
34
-  </section>
35
-  <% end %>
36
-  <nav class="w-100 bl bw1 b--silver pa3 tc flex flex-row justify-between items-center">
37
-    <%= if @paginator.page_number > 1 do %>
38
-    <a href="<%= page_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "1")) - 1}) %>" rel="previous" class="ttu navy dim link">Previous</a>
39
-    <% end %>
40
-    <%= if @paginator.page_number != @paginator.total_pages do %>
41
-      <a href="<%= page_path(@conn, :index, %{page: String.to_integer(Map.get(@conn.params, "page", "1")) + 1}) %>" rel="next" class="ttu navy dim link">Next</a>
42
-    <% end %>
43
-  </nav>
44
-</article>

+ 1
- 1
web/templates/setup/view.html.eex View File

@@ -22,4 +22,4 @@
22 22
   <input type="hidden" name="_csrf_token" value="<%= Phoenix.Controller.get_csrf_token %>" />
23 23
   <input type="hidden" name="state" value="<%= assigns[:state] %>" />
24 24
 </form>
25
-<script async defer src="<%= static_path(@conn, "/assets/js/setup.js") %>"></script>
25
+<script async defer src="<%= static_path(@conn, "/assets/setup.js") %>"></script>

+ 76
- 0
web/views/entry_view.ex View File

@@ -48,6 +48,9 @@ defmodule Koype.Web.EntryView do
48 48
   def title("view.html", %{model: model} = _assigns), do: determine_title(model.type, model)
49 49
   def title("view-gone.html", _assigns), do: "Entry Deleted"
50 50
   def title("view-notfound.html", _assigns), do: "Entry Not Found"
51
+  def title("stream.html", %{"type" => type}) when is_binary(type), do: "Stream - #{type}"
52
+  def title("stream.html", _assigns), do: "Stream - Everything"
53
+  def title("stream-empty.html", _assigns), do: "Empty Stream"
51 54
 
52 55
   def tag({:link, type}, "view.html", assigns) do
53 56
     case type do
@@ -65,6 +68,26 @@ defmodule Koype.Web.EntryView do
65 68
     end
66 69
   end
67 70
 
71
+  def tag({:link, type}, "stream.html", assigns) do
72
+    case type do
73
+      :previous ->
74
+        case assigns["page"] do
75
+          "1" -> nil
76
+          nil -> nil
77
+          page when is_binary(page) ->
78
+            index = String.to_integer(page)
79
+            entry_path(assigns[:conn], :index, %{page: index - 1})
80
+        end
81
+      :next ->
82
+        case assigns["page"] do
83
+          nil -> nil
84
+          page when is_binary(page) ->
85
+            index = String.to_integer(page)
86
+            entry_path(assigns[:conn], :index, %{page: index + 1})
87
+        end
88
+    end
89
+  end
90
+
68 91
   def tag({:meta, type}, "view.html", assigns) do
69 92
     case type do
70 93
       :description -> determine_description(assigns[:model])
@@ -72,16 +95,47 @@ defmodule Koype.Web.EntryView do
72 95
     end
73 96
   end
74 97
 
98
+  def tag({:meta, type}, "view-gone.html", assigns) do
99
+    case type do
100
+      :description -> determine_description(assigns[:model])
101
+      :author -> Koype.host()
102
+    end
103
+  end
104
+
105
+  def tag({:meta, type}, "view-notfound.html", _assigns) do
106
+    case type do
107
+      :author -> Koype.host()
108
+    end
109
+  end
110
+
111
+  def tag({:meta, type}, "stream.html", _assigns) do
112
+    case type do
113
+      :author -> Koype.host()
114
+    end
115
+  end
116
+
117
+  def tag({:meta, type}, "stream-empty.html", _assigns) do
118
+    case type do
119
+      :author -> Koype.host()
120
+    end
121
+  end
122
+
75 123
   def tag(_, _, _), do: nil
76 124
 
77 125
   def tags(:meta, "view.html", _assigns), do: ~w(description author)a
78 126
   def tags(:meta, "view-gone.html", _assigns), do: ~w(description author)a
79 127
   def tags(:meta, "view-notfound.html", _assigns), do: ~w(author)a
128
+  def tags(:meta, "stream.html", _assigns), do: ~w(author)a
129
+  def tags(:meta, "stream-empty.html", _assigns), do: ~w(author)a
80 130
 
81 131
   def tags(:link, "view.html", _assigns), do: ~w(bookmark canonical webmention)a
132
+  def tags(:link, "stream.html", _assigns), do: ~w(previous next)a
133
+  def tags(:link, "stream-empty.html", _assigns), do: ~w(bookmark canonical)a
82 134
   def tags(:link, "view-gone.html", _assigns), do: ~w(bookmark canonical webmention)a
83 135
   def tags(:link, "view-notfound.html", _assigns), do: []
84 136
 
137
+  def tags(_, _, _), do: []
138
+
85 139
   def humanize_date(str) when is_binary(str) do
86 140
     {:ok, dt} = Calendar.DateTime.Parse.rfc3339_utc(str)
87 141
     Calendar.DateTime.Format.httpdate(dt)
@@ -143,4 +197,26 @@ defmodule Koype.Web.EntryView do
143 197
         date_str
144 198
     end
145 199
   end
200
+
201
+  def render_entry_inline(%Koype.Repo.Entry{} = model) do
202
+    cond do
203
+      Enum.member?(~w(like bookmark listen read), model.type) ->
204
+        render(__MODULE__, "stream_inline-single.html", entry: model)
205
+
206
+      Enum.member?(~w(note article repost), model.type) ->
207
+        render(__MODULE__, "stream_inline-contextual.html", entry: model)
208
+
209
+      Enum.member?(~w(photo video audio), model.type) ->
210
+        case Koype.Repo.Entry.Json.find(model) do
211
+          {:ok, mf2} ->
212
+            render(__MODULE__, "stream_inline-media.html", entry: model, media_type: model.type, mf2: mf2)
213
+
214
+          {:error, _} ->
215
+            nil
216
+        end
217
+
218
+      true ->
219
+        render(__MODULE__, "stream_inline-single.html", entry: model)
220
+    end
221
+  end
146 222
 end

+ 0
- 2
web/views/page_view.ex View File

@@ -1,8 +1,6 @@
1 1
 defmodule Koype.Web.PageView do
2 2
   use Koype.Web, :view
3 3
 
4
-  def title("stream.html", _assigns), do: "Home Stream"
5
-  def title("stream-empty.html", _assigns), do: "Home Stream"
6 4
   def title("mf2.html", _assigns), do: "Microformat Parser"
7 5
 
8 6
   def tags(_, _, _), do: []

Loading…
Cancel
Save