223 Commits

Author SHA1 Message Date
DebaucheryLibrarian
4839a3b94c Allowing HTML in disclaimer. 2023-06-19 04:06:52 +02:00
DebaucheryLibrarian
d8b641e461 Removed references to effective date for older databases. 2022-02-25 22:20:28 +01:00
DebaucheryLibrarian
7b3bdadd44 1.209.4 2022-02-25 22:13:43 +01:00
DebaucheryLibrarian
5deba6b90f Passing resolved parameters into before-scrape methods. 2022-02-25 22:13:41 +01:00
DebaucheryLibrarian
a5afffc968 1.209.3 2022-02-25 00:00:21 +01:00
DebaucheryLibrarian
a239a5c593 Fixed entity scenes function for studios. Added triple anal tag alias. 2022-02-25 00:00:18 +01:00
DebaucheryLibrarian
e56e7333e3 1.209.2 2022-02-24 23:33:26 +01:00
DebaucheryLibrarian
d55e3c37cd Updated media seeds from LegalPorno to AnalVids. 2022-02-24 23:33:19 +01:00
DebaucheryLibrarian
97b78ea016 1.209.1 2022-02-24 23:30:49 +01:00
DebaucheryLibrarian
3e290b74dc Updated affiliates from LegalPorno to AnalVids. 2022-02-24 23:30:47 +01:00
DebaucheryLibrarian
65141207ae 1.209.0 2022-02-24 23:28:27 +01:00
DebaucheryLibrarian
17dfeac1af Renamed LegalPorno to AnalVids, added missing studios. 2022-02-24 23:28:24 +01:00
DebaucheryLibrarian
4a9c428d69 1.208.1 2022-02-24 22:43:01 +01:00
DebaucheryLibrarian
333f252099 Added BJ Raw to Radical. 2022-02-24 22:42:59 +01:00
DebaucheryLibrarian
38232f258a 1.208.0 2022-02-24 22:33:03 +01:00
DebaucheryLibrarian
582269cfaa Added Radical metadata layout scraper and the Got Filled and Inserted channels. 2022-02-24 22:33:00 +01:00
DebaucheryLibrarian
0b646429fd 1.207.5 2022-02-20 23:40:23 +01:00
DebaucheryLibrarian
fecef6c1cf Added missing MOFOS serie channels. 2022-02-20 23:40:20 +01:00
DebaucheryLibrarian
73e5404c44 1.207.4 2022-02-20 16:52:32 +01:00
DebaucheryLibrarian
690d2bb3ed Added MOFOS to default rate limit config, added light logos. 2022-02-20 16:52:29 +01:00
DebaucheryLibrarian
1dd935e1e9 1.207.3 2022-02-14 01:27:58 +01:00
DebaucheryLibrarian
8386230f33 Added missing Team Skeet sites. 2022-02-14 01:27:56 +01:00
DebaucheryLibrarian
5a68b06137 1.207.2 2022-02-13 01:34:41 +01:00
DebaucheryLibrarian
5918364cf5 Preventing unnecessary deep scrapes in Team Skeet scraper. 2022-02-13 01:34:39 +01:00
DebaucheryLibrarian
df4d860d35 1.207.1 2022-02-12 17:19:49 +01:00
DebaucheryLibrarian
d9f0db6e3c Fixed reading screen ID from non-existent item in Bang scraper. 2022-02-12 17:19:47 +01:00
DebaucheryLibrarian
7372b560b2 1.207.0 2022-02-12 17:16:26 +01:00
DebaucheryLibrarian
9d638c685c 1.206.12 2022-02-12 17:16:23 +01:00
DebaucheryLibrarian
5da1acc38d Added media resize. 2022-02-12 17:16:20 +01:00
DebaucheryLibrarian
c7c62e220d Removed console log from Bang scraper. 2022-02-12 16:22:41 +01:00
DebaucheryLibrarian
9edd652a2c 1.206.11 2022-02-12 16:22:03 +01:00
DebaucheryLibrarian
cde760c1ea Preventing Bang! scraper from redundant deep scraping when base release is available. 2022-02-12 16:22:00 +01:00
DebaucheryLibrarian
19c7f958e1 1.206.10 2022-02-12 03:26:43 +01:00
DebaucheryLibrarian
c7710afdbf Fixed Bang! scraped failing when scene has no photos. 2022-02-12 03:26:40 +01:00
DebaucheryLibrarian
ba18a3dadb 1.206.9 2022-02-11 22:14:46 +01:00
DebaucheryLibrarian
496c29e569 Configured Reality Kings to fetch session from RK scene overview. 2022-02-11 22:14:44 +01:00
DebaucheryLibrarian
98a72a4929 1.206.8 2022-02-09 00:19:56 +01:00
DebaucheryLibrarian
c4f0b48932 Fixed cover dimensions on movie tile to show lazy image, showing missing cover icon. 2022-02-09 00:19:54 +01:00
DebaucheryLibrarian
93abbab873 1.206.7 2022-02-08 23:59:48 +01:00
DebaucheryLibrarian
f7bbab08bd Added Porn Pros main channel and working URLs for Flexible Positions, Public Violations and Squirt Disgrace. Added bisexual tag photos. 2022-02-08 23:59:44 +01:00
DebaucheryLibrarian
1e4ddf2bbf 1.206.6 2022-02-08 00:19:36 +01:00
DebaucheryLibrarian
9b7879bff7 Removed channel ID from Gamma update query to prevent duplicate scenes. Added sexuality tags with covers to overview. 2022-02-08 00:19:34 +01:00
DebaucheryLibrarian
03d96d4dec 1.206.5 2022-02-07 22:29:11 +01:00
DebaucheryLibrarian
1dfa034332 Handling 'page not found' with 200 OK in Gamma scraper. 2022-02-07 22:29:09 +01:00
DebaucheryLibrarian
196a1d33e3 1.206.4 2022-02-07 22:16:46 +01:00
DebaucheryLibrarian
3d349c413f Fixed Adult Time scraper. 2022-02-07 22:16:43 +01:00
DebaucheryLibrarian
bd5babd37e 1.206.3 2022-02-07 21:58:31 +01:00
DebaucheryLibrarian
fffe9080f3 Added stand-alone Spizoo sites. 2022-02-07 21:58:27 +01:00
DebaucheryLibrarian
5630b16e99 1.206.2 2022-02-07 01:57:14 +01:00
DebaucheryLibrarian
4bcf7ef45b Storing associations if existing media are found. 2022-02-07 01:57:09 +01:00
DebaucheryLibrarian
9abc1d48ac 1.206.1 2022-02-05 17:14:37 +01:00
DebaucheryLibrarian
ceaf5a3217 Not storing shallow movie data when argument is disabled. 2022-02-05 17:14:34 +01:00
DebaucheryLibrarian
36d84fb98b 1.206.0 2022-02-03 00:04:51 +01:00
DebaucheryLibrarian
3d80e9d77b Added movie URL file support. Fixed Gamma movie API scraper movie URL. 2022-02-03 00:04:48 +01:00
DebaucheryLibrarian
1dc38ffacc 1.205.20 2022-02-02 23:53:44 +01:00
DebaucheryLibrarian
ee210b5c68 Replaced Gender X with Gender X Films, fixed Zero Tolerance movie URLs. 2022-02-02 23:53:42 +01:00
DebaucheryLibrarian
3aae3cd3a1 1.205.19 2022-02-02 23:51:20 +01:00
DebaucheryLibrarian
f1a7f2f905 Added Gamma movie API scraper. 2022-02-02 23:51:15 +01:00
DebaucheryLibrarian
0b7e0319f1 1.205.18 2022-02-02 22:25:06 +01:00
DebaucheryLibrarian
10b8abf706 Updated Zero Tolerance channel to Zero Tolerance Films. 2022-02-02 22:25:04 +01:00
DebaucheryLibrarian
b163223ff1 1.205.17 2022-02-01 21:18:58 +01:00
DebaucheryLibrarian
b9f3eb85f9 Ignoring Gamma master categories in update scrape as these seem to contain irrelevant tags. 2022-02-01 21:18:54 +01:00
DebaucheryLibrarian
285a65f018 1.205.16 2022-01-30 22:15:09 +01:00
DebaucheryLibrarian
815d56d334 Preventing media associations when use-reference is unavailable. 2022-01-30 22:15:07 +01:00
DebaucheryLibrarian
27a9a233e2 1.205.15 2022-01-30 17:05:20 +01:00
DebaucheryLibrarian
22864105ac Writing media associations to disk for debugging. 2022-01-30 17:05:18 +01:00
DebaucheryLibrarian
7cf47cbf8d 1.205.14 2022-01-30 00:18:17 +01:00
DebaucheryLibrarian
502c588958 Updated Bang Bros product ID for Haze Her, removed wrong ones. 2022-01-30 00:18:15 +01:00
DebaucheryLibrarian
81792a7c2f 1.205.13 2022-01-30 00:08:41 +01:00
DebaucheryLibrarian
784d326584 Updated Bang Bros product ID for College Rules. 2022-01-30 00:08:39 +01:00
DebaucheryLibrarian
83dc7aa578 1.205.12 2022-01-29 23:50:01 +01:00
DebaucheryLibrarian
5a3b27fbf7 Fixed movie cover index for overview in GraphQL query. 2022-01-29 23:49:59 +01:00
DebaucheryLibrarian
5ff83a9497 1.205.11 2022-01-29 23:39:13 +01:00
DebaucheryLibrarian
07cb39c756 Fixed movie cover index in GraphQL query. 2022-01-29 23:39:12 +01:00
DebaucheryLibrarian
fffd54995d 1.205.10 2022-01-29 17:13:13 +01:00
DebaucheryLibrarian
5302176f0b Re-added channel count to networks page. 2022-01-29 17:13:09 +01:00
DebaucheryLibrarian
efd7cf8acc 1.205.9 2022-01-29 16:38:42 +01:00
DebaucheryLibrarian
52218c30f8 Not fetching mobile Gamma page when photos are not expected. 2022-01-29 16:38:36 +01:00
DebaucheryLibrarian
04c176fa8b 1.205.8 2022-01-29 03:34:31 +01:00
DebaucheryLibrarian
af320684b4 Added Bang Bros sites. 2022-01-29 03:34:26 +01:00
DebaucheryLibrarian
b2ba14ce45 1.205.7 2022-01-29 02:39:17 +01:00
DebaucheryLibrarian
d776cc2f71 Added Abuse Me to Bang Bros network. 2022-01-29 02:39:14 +01:00
DebaucheryLibrarian
b4bed2f623 1.205.6 2022-01-29 01:21:45 +01:00
DebaucheryLibrarian
5c5a11fdca Added Bang Bros members page scraper (not for full scenes). 2022-01-29 01:21:41 +01:00
DebaucheryLibrarian
a22c62d893 1.205.5 2022-01-28 04:05:38 +01:00
DebaucheryLibrarian
90bc2f3724 Changed release media association existence check, added log for details. 2022-01-28 04:05:29 +01:00
DebaucheryLibrarian
8cdc794a3a 1.205.4 2022-01-26 13:52:41 +01:00
DebaucheryLibrarian
250618df8b Added entity scene count function. 2022-01-26 13:52:39 +01:00
DebaucheryLibrarian
b62ae00c54 1.205.3 2022-01-26 01:47:36 +01:00
DebaucheryLibrarian
67d0a9e0e0 Fixed scene entity tag association. 2022-01-26 01:47:34 +01:00
b4425bc3bb Merge pull request 'Add Facials4k' (#44) from boiii/traxxx:add-facials-4k into master
Reviewed-on: http://gitea.unknown.name/DebaucheryLibrarian/traxxx/pulls/44
2022-01-25 22:29:10 +00:00
d77c145de3 Update 'seeds/02_sites.js' 2022-01-25 20:56:11 +00:00
DebaucheryLibrarian
6753f923d9 1.205.2 2022-01-25 15:34:17 +01:00
DebaucheryLibrarian
452f725332 Switched poster URL preference in Gamma scraper to prevent cropped image on XEmpire. 2022-01-25 15:34:15 +01:00
DebaucheryLibrarian
7c1f45bcfb 1.205.1 2022-01-24 22:29:29 +01:00
DebaucheryLibrarian
11ea54f6e8 Fixed outdated alerts query. 2022-01-24 22:29:27 +01:00
DebaucheryLibrarian
5b623ee46f 1.205.0 2022-01-24 00:15:19 +01:00
DebaucheryLibrarian
7ceec1c739 Added indexes to scene tag and movie scene tables improve performance. Removed scene count from channel overview, too expensive. 2022-01-24 00:15:11 +01:00
DebaucheryLibrarian
fc318536aa 1.204.13 2022-01-23 02:46:44 +01:00
DebaucheryLibrarian
cd8f690ac6 Preferring network over channel in deep URL channel matching. 2022-01-23 02:46:42 +01:00
DebaucheryLibrarian
240a8e86fd 1.204.12 2022-01-22 23:20:10 +01:00
DebaucheryLibrarian
c557f0f1f0 Improved Gamma image sources to prevent cropped images. 2022-01-22 23:20:08 +01:00
DebaucheryLibrarian
86f56695e2 1.204.11 2022-01-20 00:54:13 +01:00
DebaucheryLibrarian
20da2d1cf6 Reusing batch ID for movies to preserve new-flag. 2022-01-20 00:54:10 +01:00
DebaucheryLibrarian
372db86927 Disabled MindGeek session bundling to analyze Too Many Requests errors. 2022-01-16 22:24:47 +01:00
DebaucheryLibrarian
4c503a3177 1.204.10 2022-01-16 17:17:49 +01:00
DebaucheryLibrarian
57d46f5842 Fixed latest query in Gamma scraper. 2022-01-16 17:17:45 +01:00
DebaucheryLibrarian
7f11d0ca91 1.204.9 2022-01-12 17:50:27 +01:00
DebaucheryLibrarian
bbd788699e Fixed GraphQL query for scenes REST API. Added entry ID to scene search document. 2022-01-12 17:50:23 +01:00
DebaucheryLibrarian
e24add98ea 1.204.8 2022-01-10 02:17:21 +01:00
DebaucheryLibrarian
506971b44b Chunked duplicate check to prevent postgres stack depth errors. 2022-01-10 02:17:17 +01:00
DebaucheryLibrarian
43a0bc8a2c 1.204.7 2022-01-07 01:07:43 +01:00
DebaucheryLibrarian
baebdbc0bb Adding comment listing sister sites for non-exclusive Gamma API scenes. 2022-01-07 01:07:41 +01:00
DebaucheryLibrarian
1c24cae3b1 1.204.6 2022-01-07 01:02:36 +01:00
DebaucheryLibrarian
b9146aee5f Removed exclusive filter from Evil Angel parameters. 2022-01-07 01:02:34 +01:00
DebaucheryLibrarian
09bfcb01f5 1.204.5 2022-01-06 01:41:29 +01:00
DebaucheryLibrarian
5d80b6dc21 Added and improved Reality Kings logos. Added tag photos. 2022-01-06 01:41:26 +01:00
DebaucheryLibrarian
140a38c349 1.204.4 2021-12-31 01:45:06 +01:00
DebaucheryLibrarian
6760c11881 Disabled why-is-node-running to assess OOM. 2021-12-31 01:45:03 +01:00
DebaucheryLibrarian
2dcdbf9c37 1.204.3 2021-12-27 22:36:03 +01:00
DebaucheryLibrarian
3b958a02ef Added memory profiler configuration options. 2021-12-27 22:36:01 +01:00
DebaucheryLibrarian
605242b399 1.204.2 2021-12-27 17:29:33 +01:00
DebaucheryLibrarian
299f257a01 Logging memory usage on media fetch. 2021-12-27 17:29:23 +01:00
DebaucheryLibrarian
0ad64ef5f4 1.204.1 2021-12-20 03:29:16 +01:00
DebaucheryLibrarian
3bfe1e8fdb Storing scenes before fetching movies. 2021-12-20 03:29:14 +01:00
DebaucheryLibrarian
7d992f4129 Added triggers to memory dump. 2021-12-20 02:28:59 +01:00
DebaucheryLibrarian
280032937f Added centralized movie page fetcher. Added memory heap dump. 2021-12-20 02:22:10 +01:00
DebaucheryLibrarian
d93670842b 1.204.0 2021-12-19 23:03:48 +01:00
DebaucheryLibrarian
dc187a9a3a Added execute method to qu, removed runScripts from Gamma's fetchMovie to observe effect on memory usage. 2021-12-19 23:03:44 +01:00
DebaucheryLibrarian
5f89c6e14c 1.203.13 2021-12-19 00:08:22 +01:00
DebaucheryLibrarian
9f10420eb9 Fixed tag search GraphQL query. 2021-12-19 00:08:21 +01:00
DebaucheryLibrarian
9568370132 1.203.12 2021-12-18 23:44:54 +01:00
DebaucheryLibrarian
1c0c30be11 Improved and re-enabled why-is-node-running logger. 2021-12-18 23:44:51 +01:00
DebaucheryLibrarian
cdb7dcd6e9 1.203.11 2021-12-18 23:22:38 +01:00
DebaucheryLibrarian
8e4be06675 Closing JSDOM window after deep scrapes in an attempt to save memory. 2021-12-18 23:22:35 +01:00
DebaucheryLibrarian
de7a8c756a 1.203.10 2021-12-13 01:20:04 +01:00
DebaucheryLibrarian
65e2b72c6a Fixed Gamma movie scraper failing when data object is not available. 2021-12-13 01:20:02 +01:00
DebaucheryLibrarian
523c36ecd4 1.203.9 2021-12-11 22:46:58 +01:00
DebaucheryLibrarian
5b5688438c Fixed Gamma movie scene query. Added tag photos. 2021-12-11 22:46:55 +01:00
DebaucheryLibrarian
4ca07631c7 1.203.8 2021-12-05 23:59:20 +01:00
DebaucheryLibrarian
ec4e7bc12a Updated Jules Jordan scraper for Sperm Swallowers and The Ass Factory. 2021-12-05 23:59:17 +01:00
DebaucheryLibrarian
26d15c0a6f Updated Jules Jordan scraper for Manuel Ferrara and Girl Girl. 2021-12-05 23:43:23 +01:00
DebaucheryLibrarian
a484396db4 Hiding scenes with missing dates from network overview. Using computed effective date column. 2021-12-05 23:29:27 +01:00
DebaucheryLibrarian
681db02784 1.203.7 2021-12-05 02:54:57 +01:00
DebaucheryLibrarian
e88554666c Reduced media concurrency to assess effect on memory. Moved qu context removal to deep scrape runner. Updated movie graphql queries. 2021-12-05 02:54:55 +01:00
DebaucheryLibrarian
9f37ec4cff 1.203.6 2021-12-04 00:32:31 +01:00
DebaucheryLibrarian
abd063a578 Removed window map from http module to prevent memory pile-up with update scraping. 2021-12-04 00:32:28 +01:00
DebaucheryLibrarian
883e57ce1f 1.203.5 2021-12-02 15:51:33 +01:00
DebaucheryLibrarian
ad04502a8c Added Radical favicons. 2021-12-02 15:51:30 +01:00
DebaucheryLibrarian
f65ed16842 1.203.4 2021-12-02 00:45:24 +01:00
DebaucheryLibrarian
1918dd4ad5 Removing query methods from XEmpire release. 2021-12-02 00:45:22 +01:00
DebaucheryLibrarian
3983d3464f 1.203.3 2021-12-01 23:44:27 +01:00
DebaucheryLibrarian
61daf5f037 Added debug log for jsdom window closing. 2021-12-01 23:44:25 +01:00
DebaucheryLibrarian
eafa144104 1.203.2 2021-12-01 23:39:11 +01:00
DebaucheryLibrarian
60c151ff6a Reduced deep scrape concurrency to 1. 2021-12-01 23:39:09 +01:00
DebaucheryLibrarian
c97d18fcf9 1.203.1 2021-12-01 23:30:12 +01:00
DebaucheryLibrarian
e41f9fa937 Added waitImmediate to deep scrape, reduced concurrency. 2021-12-01 23:30:10 +01:00
DebaucheryLibrarian
56a7fb0ad9 1.203.0 2021-12-01 17:26:34 +01:00
DebaucheryLibrarian
e29cbc9fea Closing JSDOM window after deep scrape in an attempt to save memory. Reduced deep scrape concurrency to 5. 2021-12-01 17:26:13 +01:00
DebaucheryLibrarian
08f725a0b6 1.202.3 2021-12-01 00:00:26 +01:00
DebaucheryLibrarian
b93a5715cb Updated Jules Jordan scraper for new update page layout. 2021-12-01 00:00:24 +01:00
DebaucheryLibrarian
2018d5c298 1.202.2 2021-11-29 02:49:12 +01:00
DebaucheryLibrarian
87094a9498 Replaced cheerio with qu in Gamma scraper. 2021-11-29 02:49:07 +01:00
DebaucheryLibrarian
53a1c697d0 1.202.1 2021-11-28 01:20:41 +01:00
DebaucheryLibrarian
f04eb72891 Added upcoming scraper to PurgatoryX. 2021-11-28 01:20:39 +01:00
DebaucheryLibrarian
dfeb0c08cf 1.202.0 2021-11-27 23:55:22 +01:00
DebaucheryLibrarian
9d7183ac69 Added PurgatoryX scraper. 2021-11-27 23:55:16 +01:00
DebaucheryLibrarian
2539e88f47 1.201.6 2021-11-22 02:51:55 +01:00
DebaucheryLibrarian
20d0d860d3 Fixed MindGeek scraper trying to acquire session from mindgeek.com 2021-11-22 02:51:52 +01:00
DebaucheryLibrarian
6b4aa64d74 Improved MindGeek scraper session check to prevent crash when network session isn't available yet. 2021-11-22 02:44:03 +01:00
DebaucheryLibrarian
c7b9ec7a4b 1.201.5 2021-11-21 00:47:34 +01:00
DebaucheryLibrarian
e81864ebde Removed verbose http queued output. 2021-11-21 00:47:32 +01:00
DebaucheryLibrarian
0305a22a24 Removed stray console log from media module. 2021-11-21 00:43:35 +01:00
DebaucheryLibrarian
a406eb584d 1.201.4 2021-11-21 00:41:15 +01:00
DebaucheryLibrarian
2be3ea9bbb Explicitly adding headers to http module result. 2021-11-21 00:41:12 +01:00
DebaucheryLibrarian
0a8a7ff9a5 1.201.3 2021-11-21 00:31:12 +01:00
DebaucheryLibrarian
98c103c625 Fixed uuid import. Changed fs rmdir to rm. 2021-11-21 00:31:09 +01:00
DebaucheryLibrarian
e0908a5f5e 1.201.2 2021-11-21 00:19:13 +01:00
DebaucheryLibrarian
f0b7678444 Fixed upsert failing on empty insert array due breaking Knex API change. 2021-11-21 00:19:10 +01:00
DebaucheryLibrarian
64e9efe095 1.201.1 2021-11-21 00:15:21 +01:00
DebaucheryLibrarian
ab29ab053e Increased tile heart button size. Hiding entity tile info under hover effect. 2021-11-21 00:15:19 +01:00
DebaucheryLibrarian
a5081bc7c9 Updated primary color. 2021-11-21 00:04:21 +01:00
DebaucheryLibrarian
da9c628f9b 1.201.0 2021-11-21 00:00:14 +01:00
DebaucheryLibrarian
26539b74a5 Updated dependencies. Added periodic memory logger. 2021-11-20 23:59:48 +01:00
DebaucheryLibrarian
a867817dc1 Improved scene tile scaling. 2021-10-31 01:00:12 +02:00
DebaucheryLibrarian
d1e05915b5 Tweaked scene and actor tile design, tags grid breakpoints. 2021-10-31 00:31:18 +02:00
DebaucheryLibrarian
b764fdec85 Showing scene and channel count on entity page and tile. 2021-10-30 22:41:58 +02:00
DebaucheryLibrarian
8322d43b09 1.200.2 2021-10-28 02:10:37 +02:00
DebaucheryLibrarian
29b8c5e38e Including unextracted scenes in date determination. 2021-10-28 02:10:30 +02:00
DebaucheryLibrarian
83dd233991 1.200.1 2021-10-28 02:00:04 +02:00
DebaucheryLibrarian
0864154a0e Added unextracted property to keep paginating when extracting scenes. 2021-10-28 01:59:53 +02:00
DebaucheryLibrarian
53357d4bd2 1.200.0 2021-10-27 17:19:33 +02:00
DebaucheryLibrarian
69bf98edf1 1.199.17 2021-10-27 17:19:30 +02:00
DebaucheryLibrarian
a22c4d5679 Added beforeNetwork hook, used by MindGeek. Added Filthy Kings to Gamma. 2021-10-27 17:19:23 +02:00
DebaucheryLibrarian
e5ad1648eb 1.199.16 2021-10-26 23:42:42 +02:00
DebaucheryLibrarian
100a35b4e8 Added before scene fetch method to prevent e.g. unnecessary session requests, moved scraper assignment to entity lookup. Removed channel URL hostname matching.. 2021-10-26 23:42:32 +02:00
DebaucheryLibrarian
6c5d4389fe Not parsing HTML with jsdom when using http module directly to save memory. Added loading ellipsis to release grid pages. 2021-10-25 02:06:24 +02:00
DebaucheryLibrarian
92f9ff4104 1.199.15 2021-10-20 01:47:04 +02:00
DebaucheryLibrarian
0e4fd12d70 Added more loggers to http module. 2021-10-20 01:46:56 +02:00
DebaucheryLibrarian
9040285ce5 1.199.14 2021-10-17 23:57:10 +02:00
DebaucheryLibrarian
972b15e72d Added memory profiling. 2021-10-17 23:56:49 +02:00
DebaucheryLibrarian
c1aea78496 1.199.13 2021-10-17 19:59:11 +02:00
DebaucheryLibrarian
49f891ba44 Ignoring 1-second scene duration from MindGeek API. 2021-10-17 19:59:05 +02:00
DebaucheryLibrarian
239057f1b6 1.199.12 2021-10-17 00:28:18 +02:00
DebaucheryLibrarian
167df35d37 Fixed tags module not dealing with empty releases or tags, added origin tag column to chapter tag table. 2021-10-17 00:28:13 +02:00
DebaucheryLibrarian
b1b2ad2111 1.199.11 2021-10-11 04:31:46 +02:00
DebaucheryLibrarian
f1ff662be2 Fixed tags seed file. 2021-10-11 04:31:40 +02:00
DebaucheryLibrarian
2418fec9c9 1.199.10 2021-10-11 02:16:58 +02:00
DebaucheryLibrarian
aaaa0a6afb Updated proxy list. 2021-10-11 02:16:51 +02:00
DebaucheryLibrarian
afe22003e1 1.199.9 2021-10-10 00:04:28 +02:00
DebaucheryLibrarian
b6ad2903f3 Storing original tags. 2021-10-10 00:04:21 +02:00
DebaucheryLibrarian
6c298cd639 1.199.8 2021-09-28 20:45:30 +02:00
DebaucheryLibrarian
dbff3e9539 Added Brad Montana. Added teaser link to trailer video. 2021-09-28 20:45:22 +02:00
DebaucheryLibrarian
fcc6b33d07 1.199.7 2021-09-17 04:28:54 +02:00
DebaucheryLibrarian
0224c26ca0 Fixed alert searches. Added Teen Mega World campaigns. 2021-09-17 04:28:48 +02:00
DebaucheryLibrarian
294f15e694 1.199.6 2021-09-17 03:30:58 +02:00
DebaucheryLibrarian
522584711b Added Teen Mega World scraper. 2021-09-17 03:30:49 +02:00
DebaucheryLibrarian
ae40f33283 Added Transfixed to Adult Time. 2021-09-16 16:57:14 +02:00
DebaucheryLibrarian
172e01c80e Added Score to default ignored networks. 2021-09-15 02:01:13 +02:00
DebaucheryLibrarian
901acf1390 1.199.5 2021-09-14 00:42:59 +02:00
DebaucheryLibrarian
a316da3083 Retrieving Spizoo trailers. 2021-09-14 00:42:51 +02:00
DebaucheryLibrarian
0b46e27497 1.199.4 2021-09-13 01:29:47 +02:00
DebaucheryLibrarian
b164c5dad7 Added Spizoo. 2021-09-13 01:29:39 +02:00
1409 changed files with 31422 additions and 6370 deletions

View File

@@ -2,7 +2,7 @@
"root": true, "root": true,
"extends": ["airbnb-base", "plugin:vue/recommended"], "extends": ["airbnb-base", "plugin:vue/recommended"],
"parserOptions": { "parserOptions": {
"parser": "babel-eslint", "parser": "@babel/eslint-parser",
"ecmaVersion": 2019, "ecmaVersion": 2019,
"sourceType": "module" "sourceType": "module"
}, },
@@ -17,10 +17,11 @@
"vue/html-indent": ["error", "tab"], "vue/html-indent": ["error", "tab"],
"vue/multiline-html-element-content-newline": 0, "vue/multiline-html-element-content-newline": 0,
"vue/singleline-html-element-content-newline": 0, "vue/singleline-html-element-content-newline": 0,
"vue/multi-word-component-names": 0,
"no-param-reassign": ["error", { "no-param-reassign": ["error", {
"props": true, "props": true,
"ignorePropertyModificationsFor": ["state", "acc"] "ignorePropertyModificationsFor": ["state", "acc"]
}], }]
}, },
"globals": { "globals": {
"CONFIG": true "CONFIG": true

3
.gitignore vendored
View File

@@ -2,9 +2,12 @@ node_modules/
dist/ dist/
log/ log/
media/ media/
html/
public/js/* public/js/*
public/css/* public/css/*
config/* config/*
!config/default.js !config/default.js
assets/js/config/ assets/js/config/
!assets/js/config/default.js !assets/js/config/default.js
*.heapprofile
*.heapsnapshot

2
.nvmrc
View File

@@ -1 +1 @@
14.15.4 16.13.0

View File

@@ -6,7 +6,7 @@
<div class="actor-header"> <div class="actor-header">
<h2 class="header-name"> <h2 class="header-name">
<span v-if="actor.entity">{{ actor.name }} ({{ actor.entity.name }})</span> <span v-if="actor.entity">{{ actor.name }} ({{ actor.entity.name }})</span>
<span v-else="">{{ actor.name }}</span> <span v-else>{{ actor.name }}</span>
<Gender <Gender
:gender="actor.gender" :gender="actor.gender"
@@ -361,7 +361,10 @@
:available-actors="actor.actors" :available-actors="actor.actors"
/> />
<Releases :releases="releases" /> <Releases
:releases="releases"
:done="done"
/>
<Pagination <Pagination
:items-total="totalCount" :items-total="totalCount"
@@ -389,6 +392,8 @@ import Social from './social.vue';
import StashButton from '../stashes/button.vue'; import StashButton from '../stashes/button.vue';
async function fetchActor(scroll = true) { async function fetchActor(scroll = true) {
this.done = false;
const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', { const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', {
actorId: Number(this.$route.params.actorId), actorId: Number(this.$route.params.actorId),
limit: this.limit, limit: this.limit,
@@ -400,6 +405,7 @@ async function fetchActor(scroll = true) {
this.releases = releases; this.releases = releases;
this.totalCount = totalCount; this.totalCount = totalCount;
this.stashedBy = actor.stashes; this.stashedBy = actor.stashes;
this.done = true;
if (this.$refs.filter && scroll) { if (this.$refs.filter && scroll) {
this.$refs.filter.$el.scrollIntoView(); this.$refs.filter.$el.scrollIntoView();
@@ -463,6 +469,7 @@ export default {
return { return {
actor: null, actor: null,
releases: null, releases: null,
done: false,
totalCount: 0, totalCount: 0,
limit: 20, limit: 20,
pageTitle: null, pageTitle: null,

View File

@@ -272,7 +272,7 @@ import Pagination from '../pagination/pagination.vue';
const toggleValues = [true, null, false]; const toggleValues = [true, null, false];
const boobSizes = 'ABCDEFGHIJKZ'.split(''); const boobSizes = 'ABCDEFGHIJKZ'.split('');
const topCountries = ['AU', 'BR', 'DE', 'JP', 'RU', 'GB', 'US']; const topCountries = ['AU', 'BR', 'CZ', 'DE', 'JP', 'RU', 'GB', 'US'];
function updateFilters() { function updateFilters() {
this.$router.push({ this.$router.push({

View File

@@ -214,7 +214,7 @@ export default {
display: inline-block; display: inline-block;
position: relative; position: relative;
box-shadow: 0 0 3px var(--darken-weak); box-shadow: 0 0 3px var(--darken-weak);
background: var(--background); background: var(--info);
overflow: hidden; overflow: hidden;
&::before { &::before {
@@ -237,12 +237,8 @@ export default {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
color: var(--text); color: var(--text-light);
text-decoration: none; text-decoration: none;
&:hover {
color: var(--primary);
}
} }
.handle { .handle {
@@ -253,7 +249,8 @@ export default {
box-shadow: 0 0 3px var(--shadow); box-shadow: 0 0 3px var(--shadow);
.name { .name {
padding: .5rem; padding: .25rem .5rem;
font-size: .9rem;
} }
.alias { .alias {
@@ -316,8 +313,8 @@ export default {
} }
.stash { .stash {
width: 1.25rem; width: 1.5rem;
height: 1.25rem; height: 1.5rem;
padding: .25rem .25rem .5rem .5rem; padding: .25rem .25rem .5rem .5rem;
position: absolute; position: absolute;
top: 0; top: 0;

View File

@@ -46,7 +46,7 @@
/> />
</li> </li>
<template v-slot:tooltip> <template #tooltip>
<Search <Search
content="actors" content="actors"
@select="actor => addActor(actor)" @select="actor => addActor(actor)"
@@ -88,7 +88,7 @@
/> />
</li> </li>
<template v-slot:tooltip> <template #tooltip>
<Search <Search
content="tags" content="tags"
:defaults="['anal', 'blowbang', 'mfm', 'dp', 'gangbang', 'airtight']" :defaults="['anal', 'blowbang', 'mfm', 'dp', 'gangbang', 'airtight']"
@@ -126,7 +126,7 @@
/> />
</div> </div>
<template v-slot:tooltip> <template #tooltip>
<Search <Search
label="Search channels" label="Search channels"
content="entities" content="entities"
@@ -181,7 +181,7 @@
/> />
</li> </li>
<template v-slot:tooltip> <template #tooltip>
<Search <Search
content="stashes" content="stashes"
@select="stash => addStash(stash)" @select="stash => addStash(stash)"
@@ -194,6 +194,7 @@
<div class="dialog-actions right"> <div class="dialog-actions right">
<button <button
:disabled="actors.length === 0 && tags.length === 0 && !entity"
type="submit" type="submit"
class="button button-primary" class="button button-primary"
>Add alert</button> >Add alert</button>
@@ -210,19 +211,19 @@ import Search from './search.vue';
async function addAlert() { async function addAlert() {
await this.$store.dispatch('addAlert', { await this.$store.dispatch('addAlert', {
actors: this.actors.map(actor => actor.id), actors: this.actors.map((actor) => actor.id),
tags: this.tags.map(tag => tag.id), tags: this.tags.map((tag) => tag.id),
entity: this.entity?.id, entity: this.entity?.id,
notify: this.notify, notify: this.notify,
email: this.email, email: this.email,
stashes: this.stashes.map(stash => stash.id), stashes: this.stashes.map((stash) => stash.id),
}); });
this.$emit('close', true); this.$emit('close', true);
} }
function addActor(actor) { function addActor(actor) {
if (!this.actors.some(selectedActor => selectedActor.id === actor.id)) { if (!this.actors.some((selectedActor) => selectedActor.id === actor.id)) {
this.actors = this.actors.concat(actor); this.actors = this.actors.concat(actor);
} }
@@ -235,7 +236,7 @@ function addEntity(entity) {
} }
function addTag(tag) { function addTag(tag) {
if (!this.tags.some(selectedTag => selectedTag.id === tag.id)) { if (!this.tags.some((selectedTag) => selectedTag.id === tag.id)) {
this.tags = this.tags.concat(tag); this.tags = this.tags.concat(tag);
} }
@@ -243,7 +244,7 @@ function addTag(tag) {
} }
function removeActor(actor) { function removeActor(actor) {
this.actors = this.actors.filter(listedActor => listedActor.id !== actor.id); this.actors = this.actors.filter((listedActor) => listedActor.id !== actor.id);
} }
function removeEntity() { function removeEntity() {
@@ -251,11 +252,11 @@ function removeEntity() {
} }
function removeTag(tag) { function removeTag(tag) {
this.tags = this.tags.filter(listedTag => listedTag.id !== tag.id); this.tags = this.tags.filter((listedTag) => listedTag.id !== tag.id);
} }
function addStash(stash) { function addStash(stash) {
if (!this.stashes.some(selectedStash => selectedStash.id === stash.id)) { if (!this.stashes.some((selectedStash) => selectedStash.id === stash.id)) {
this.stashes = this.stashes.concat(stash); this.stashes = this.stashes.concat(stash);
} }
@@ -263,7 +264,7 @@ function addStash(stash) {
} }
function removeStash(stash) { function removeStash(stash) {
this.stashes = this.stashes.filter(listedStash => listedStash.id !== stash.id); this.stashes = this.stashes.filter((listedStash) => listedStash.id !== stash.id);
} }
export default { export default {
@@ -273,6 +274,7 @@ export default {
Entity, Entity,
Search, Search,
}, },
emits: ['close'],
data() { data() {
return { return {
actors: [], actors: [],
@@ -284,7 +286,6 @@ export default {
availableStashes: this.$store.state.auth.user.stashes, availableStashes: this.$store.state.auth.user.stashes,
}; };
}, },
emits: ['close'],
methods: { methods: {
addActor, addActor,
addAlert, addAlert,

View File

@@ -43,11 +43,12 @@
<script> <script>
async function search() { async function search() {
if (this.content === 'actors') { if (this.content === 'actors') {
this.results = await this.$store.dispatch('searchActors', { const { actors } = await this.$store.dispatch('fetchActors', {
query: this.query, query: this.query,
minLength: 1,
limit: 10, limit: 10,
}); });
this.results = actors;
} }
if (this.content === 'entities') { if (this.content === 'entities') {

View File

@@ -35,11 +35,11 @@
class="button button-primary" class="button button-primary"
>Log in</button> >Log in</button>
<router-link <RouterLink
v-if="$store.state.auth.signup" v-if="$store.state.auth.signup"
:to="{ name: 'signup', query: { ref: $route.query.ref } }" :to="{ name: 'signup', query: { ref: $route.query.ref } }"
class="link link-external signup" class="link link-external signup"
>Sign up</router-link> >Sign up</RouterLink>
</template> </template>
</form> </form>
</template> </template>

View File

@@ -43,11 +43,11 @@
class="button button-primary" class="button button-primary"
>Sign up</button> >Sign up</button>
<router-link <RouterLink
v-if="$store.state.auth.login" v-if="$store.state.auth.login"
:to="{ name: 'login', query: { ref: $route.query.ref } }" :to="{ name: 'login', query: { ref: $route.query.ref } }"
class="link link-external login" class="link link-external login"
>Log in</router-link> >Log in</RouterLink>
</template> </template>
</form> </form>
</template> </template>

54
assets/components/container/container.vue Normal file → Executable file
View File

@@ -8,35 +8,40 @@
/> />
<transition name="slide"> <transition name="slide">
<Sidebar <Sidebar v-if="showSidebar" />
v-if="showSidebar"
@toggle-sidebar="(state) => toggleSidebar(state)"
@show-filters="(state) => toggleFilters(state)"
/>
</transition> </transition>
<Header <Header />
@toggle-sidebar="(state) => toggleSidebar(state)"
@show-filters="(state) => toggleFilters(state)"
/>
<p <p
v-if="config.showDisclaimer" v-if="config.showDisclaimer"
class="disclaimer" class="disclaimer"
>{{ config.disclaimer }}</p> v-html="config.disclaimer"
/>
<p
v-if="config.showAnnouncement"
class="announcement"
v-html="config.announcement"
/>
<div <div
ref="content" ref="content"
class="content" class="content"
@scroll="scroll" @scroll="scroll"
> >
<router-view @scroll="scrollToTop" /> <RouterView @scroll="scrollToTop" />
</div> </div>
<Filters <Filters
v-if="showFilters" v-if="showFilters"
@close="toggleFilters(false)" @close="toggleFilters(false)"
/> />
<Settings
v-if="showSettings"
@close="toggleSettings(false)"
/>
</div> </div>
</template> </template>
@@ -45,6 +50,7 @@ import Warning from './warning.vue';
import Header from '../header/header.vue'; import Header from '../header/header.vue';
import Sidebar from '../sidebar/sidebar.vue'; import Sidebar from '../sidebar/sidebar.vue';
import Filters from '../filters/filters.vue'; import Filters from '../filters/filters.vue';
import Settings from '../settings/settings.vue';
function toggleSidebar(state) { function toggleSidebar(state) {
this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar; this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar;
@@ -55,6 +61,11 @@ function toggleFilters(state) {
this.showSidebar = false; this.showSidebar = false;
} }
function toggleSettings(state) {
this.showSettings = state;
this.showSidebar = false;
}
async function setConsent(consent, includeQueer) { async function setConsent(consent, includeQueer) {
if (consent) { if (consent) {
this.showWarning = false; this.showWarning = false;
@@ -62,7 +73,7 @@ async function setConsent(consent, includeQueer) {
} }
if (includeQueer) { if (includeQueer) {
this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter(tag => !['gay', 'bisexual', 'transsexual'].includes(tag))); this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter((tag) => !['gay', 'bisexual', 'transsexual'].includes(tag)));
return; return;
} }
@@ -88,6 +99,9 @@ function scrollToTop() {
function mounted() { function mounted() {
document.addEventListener('click', this.blur); document.addEventListener('click', this.blur);
window.addEventListener('resize', this.resize); window.addEventListener('resize', this.resize);
this.events.on('toggleSettings', this.toggleSettings);
this.events.on('toggleSidebar', this.toggleSidebar);
} }
function beforeUnmount() { function beforeUnmount() {
@@ -101,12 +115,15 @@ export default {
Sidebar, Sidebar,
Warning, Warning,
Filters, Filters,
Settings,
}, },
data() { data() {
return { return {
showSidebar: false, showSidebar: false,
showWarning: localStorage.getItem('consent') !== window.env.sessionId, showWarning: localStorage.getItem('consent') !== window.env.sessionId,
showFilters: false, showFilters: false,
showSettings: false,
selected: null,
}; };
}, },
mounted, mounted,
@@ -114,6 +131,7 @@ export default {
methods: { methods: {
toggleSidebar, toggleSidebar,
toggleFilters, toggleFilters,
toggleSettings,
setConsent, setConsent,
blur, blur,
resize, resize,
@@ -183,13 +201,21 @@ export default {
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.disclaimer { .disclaimer,
.announcement {
padding: .5rem 1rem; padding: .5rem 1rem;
margin: 0; margin: 0;
color: var(--text-light); color: var(--text-light);
background: var(--warn);
font-weight: bold; font-weight: bold;
box-shadow: inset 0 0 3px var(--darken-weak); box-shadow: inset 0 0 3px var(--darken-weak);
text-align: center; text-align: center;
} }
.disclaimer {
background: var(--warn);
}
.announcement {
background: var(--notice);
}
</style> </style>

View File

@@ -116,6 +116,7 @@ export default {
::v-deep(.dialog-body) { ::v-deep(.dialog-body) {
padding: 1rem; padding: 1rem;
flex-grow: 1; flex-grow: 1;
overflow-y: auto;
} }
::v-deep(.dialog-section:not(:last-child)) { ::v-deep(.dialog-section:not(:last-child)) {

View File

@@ -51,7 +51,7 @@
>{{ tag.name }}</li> >{{ tag.name }}</li>
</ul> </ul>
<router-link <RouterLink
v-if="entity.parent" v-if="entity.parent"
:to="`/${entity.parent.type}/${entity.parent.slug}`" :to="`/${entity.parent.type}/${entity.parent.slug}`"
class="link link-parent" class="link link-parent"
@@ -74,7 +74,7 @@
>{{ entity.parent.name }}</h3> >{{ entity.parent.name }}</h3>
<Icon icon="device_hub" /> <Icon icon="device_hub" />
</router-link> </RouterLink>
</div> </div>
<div <div
@@ -111,7 +111,10 @@
/> />
<div class="releases"> <div class="releases">
<Releases :releases="entity.releases" /> <Releases
:releases="entity.releases"
:done="done"
/>
<Pagination <Pagination
:items-total="totalCount" :items-total="totalCount"
@@ -134,6 +137,7 @@ import Scroll from '../scroll/scroll.vue';
import Campaign from '../campaigns/campaign.vue'; import Campaign from '../campaigns/campaign.vue';
async function fetchEntity(scroll = true) { async function fetchEntity(scroll = true) {
this.done = false;
this.entityUrl = null; this.entityUrl = null;
const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', { const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', {
@@ -149,8 +153,8 @@ async function fetchEntity(scroll = true) {
this.pageTitle = entity.name; this.pageTitle = entity.name;
const campaign = entity.campaigns.find(campaignX => !campaignX.banner) const campaign = entity.campaigns.find((campaignX) => !campaignX.banner)
|| entity.parent?.campaigns.find(campaignX => !campaignX.banner); || entity.parent?.campaigns.find((campaignX) => !campaignX.banner);
const affiliateParams = new URLSearchParams({ const affiliateParams = new URLSearchParams({
...(entity.url && Object.fromEntries(new URL(entity.url).searchParams)), // preserve any query in entity URL, e.g. ?siteId=5 ...(entity.url && Object.fromEntries(new URL(entity.url).searchParams)), // preserve any query in entity URL, e.g. ?siteId=5
@@ -158,6 +162,7 @@ async function fetchEntity(scroll = true) {
}).toString(); }).toString();
this.entityUrl = campaign?.url || campaign?.affiliate?.url || `${entity.url}${campaign?.affiliate?.parameters ? `?${affiliateParams}` : ''}`; this.entityUrl = campaign?.url || campaign?.affiliate?.url || `${entity.url}${campaign?.affiliate?.parameters ? `?${affiliateParams}` : ''}`;
this.done = true;
if (scroll && this.$refs.filter?.$el) { if (scroll && this.$refs.filter?.$el) {
this.$refs.filter.$el.scrollIntoView(); this.$refs.filter.$el.scrollIntoView();
@@ -189,6 +194,7 @@ export default {
entity: null, entity: null,
pageTitle: null, pageTitle: null,
totalCount: null, totalCount: null,
done: false,
limit: Number(this.$route.query.limit) || 20, limit: Number(this.$route.query.limit) || 20,
expanded: false, expanded: false,
entityUrl: null, entityUrl: null,

View File

@@ -4,39 +4,49 @@
:title="entity.name" :title="entity.name"
class="tile" class="tile"
> >
<template v-if="entity.hasLogo"> <div class="tile-logo">
<img <template v-if="entity.hasLogo">
v-if="entity.type === 'network' || entity.independent" <img
:src="`/img/logos/${entity.slug}/thumbs/network.png`" v-if="entity.type === 'network' || entity.independent"
:alt="entity.name" :src="`/img/logos/${entity.slug}/thumbs/network.png`"
loading="lazy" :alt="entity.name"
class="logo" loading="lazy"
@load="$emit('load', $event)" class="logo"
> @load="$emit('load', $event)"
>
<img <img
v-else-if="entity.parent" v-else-if="entity.parent"
:src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`" :src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`"
:alt="entity.name" :alt="entity.name"
loading="lazy" loading="lazy"
class="logo" class="logo"
@load="$emit('load', $event)" @load="$emit('load', $event)"
> >
<img <img
v-else
:src="`/img/logos/${entity.slug}/thumbs/${entity.slug}.png`"
:alt="entity.name"
loading="lazy"
class="logo"
@load="$emit('load', $event)"
>
</template>
<span
v-else v-else
:src="`/img/logos/${entity.slug}/thumbs/${entity.slug}.png`" class="name"
:alt="entity.name" >{{ entity.name }}</span>
loading="lazy" </div>
class="logo"
@load="$emit('load', $event)"
>
</template>
<span <span
v-else v-if="entity.childrenTotal > 0 || typeof entity.sceneTotal !== 'undefined'"
class="name" class="count"
>{{ entity.name }}</span> >
<span v-if="typeof entity.sceneTotal !== 'undefined'">{{ entity.sceneTotal }} scenes</span>
<span v-if="entity.type === 'network'">{{ entity.childrenTotal }} channels</span>
</span>
</router-link> </router-link>
</template> </template>
@@ -59,15 +69,28 @@ export default {
height: 100%; height: 100%;
background: var(--tile); background: var(--tile);
display: flex; display: flex;
flex-direction: column;
flex-shrink: 0; flex-shrink: 0;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: .5rem 1rem;
border-radius: .25rem; border-radius: .25rem;
position: relative;
box-shadow: 0 0 3px rgba(0, 0, 0, .25); box-shadow: 0 0 3px rgba(0, 0, 0, .25);
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
overflow: hidden;
&:hover .count {
bottom: 0;
}
}
.tile-logo {
display: flex;
flex-grow: 1;
padding: .5rem 1rem;
overflow: hidden;
} }
.logo { .logo {
@@ -75,6 +98,7 @@ export default {
max-height: 100%; max-height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
align-self: center;
} }
.name { .name {
@@ -82,4 +106,20 @@ export default {
font-size: 1.25rem; font-size: 1.25rem;
font-weight: bold; font-weight: bold;
} }
.count {
display: flex;
justify-content: space-between;
width: 100%;
position: absolute;
bottom: -1.75rem;
box-sizing: border-box;
padding: .25rem .5rem;
background: var(--darken-strong);
box-shadow: 0 0 3px var(--darken);
color: var(--text-light);
text-align: center;
text-shadow: 1px 1px var(--darken);
transition: bottom .1s ease;
}
</style> </style>

View File

@@ -1,31 +1,33 @@
<template> <template>
<div class="filter-bar noselect"> <div class="filter-bar noselect">
<div class="sort"> <div class="sort">
<router-link <RouterLink
v-for="section in ranges" v-for="section in ranges"
:key="section" :key="section"
:to="{ params: { range: section, pageNumber: 1 }, query: $route.query }" :to="{ params: { range: section, pageNumber: 1 }, query: $route.query }"
:class="{ active: $route.name === section || range === section }" :class="{ active: $route.name === section || range === section }"
class="range range-button" class="range range-button"
>{{ section }}</router-link> >{{ section }}</RouterLink>
</div> </div>
<span
v-if="itemsTotal && showTotal"
class="total"
>{{ itemsTotal }} <template v-if="itemsTotal === 1">scene</template><template v-else>scenes</template></span>
<div class="filters"> <div class="filters">
<ActorFilter <ActorFilter
class="filters-filter" class="filters-filter"
:filter="filter"
:available-actors="availableActors" :available-actors="availableActors"
/> />
<ChannelFilter <ChannelFilter
class="filters-filter" class="filters-filter"
:filter="filter"
:available-channels="availableChannels" :available-channels="availableChannels"
/> />
<TagFilter <TagFilter
class="filters-filter" class="filters-filter"
:filter="filter"
:available-tags="availableTags" :available-tags="availableTags"
/> />
</div> </div>
@@ -39,10 +41,6 @@ import ActorFilter from './actor-filter.vue';
import ChannelFilter from './channel-filter.vue'; import ChannelFilter from './channel-filter.vue';
import TagFilter from './tag-filter.vue'; import TagFilter from './tag-filter.vue';
function filter(state) {
return state.ui.filter;
}
function range() { function range() {
return this.$route.params.range; return this.$route.params.range;
} }
@@ -78,6 +76,10 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
showTotal: {
type: Boolean,
default: true,
},
itemsTotal: { itemsTotal: {
type: Number, type: Number,
default: 0, default: 0,
@@ -105,7 +107,6 @@ export default {
}, },
computed: { computed: {
...mapState({ ...mapState({
filter,
range, range,
batch, batch,
}), }),
@@ -120,6 +121,43 @@ export default {
<style lang="scss"> <style lang="scss">
@import 'breakpoints'; @import 'breakpoints';
.filter {
color: var(--shadow);
display: inline-flex;
align-items: center;
.filter-applied {
flex-grow: 1;
padding: .75rem .5rem;
font-size: 1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: right;
&.empty {
color: var(--shadow);
}
}
.icon {
fill: var(--shadow);
margin: -.1rem 0 0 0;
}
&:hover {
cursor: pointer;
.applied {
color: var(--shadow-strong);
}
.icon {
fill: var(--shadow-strong);
}
}
}
.filter-mode { .filter-mode {
width: 100%; width: 100%;
color: var(--shadow); color: var(--shadow);
@@ -240,6 +278,10 @@ export default {
.filters-filter:last-child .filter { .filters-filter:last-child .filter {
padding: .5rem 0 .5rem .5rem; padding: .5rem 0 .5rem .5rem;
} }
.total {
display: none;
}
} }
</style> </style>
@@ -261,43 +303,6 @@ export default {
} }
} }
::v-deep(.filter) {
color: var(--shadow);
display: inline-flex;
align-items: center;
.filter-applied {
flex-grow: 1;
padding: .75rem .5rem;
font-size: 1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: right;
&.empty {
color: var(--shadow);
}
}
.icon {
fill: var(--shadow);
margin: -.1rem 0 0 0;
}
&:hover {
cursor: pointer;
.applied {
color: var(--shadow-strong);
}
.icon {
fill: var(--shadow-strong);
}
}
}
.filters { .filters {
flex-shrink: 0; flex-shrink: 0;
} }
@@ -351,4 +356,11 @@ export default {
margin: 0 1rem 0 0; margin: 0 1rem 0 0;
} }
} }
.total {
flex-shrink: 0;
padding: 0 1rem;
color: var(--shadow);
font-size: .8rem;
}
</style> </style>

View File

@@ -14,7 +14,7 @@
>Tags</div> >Tags</div>
</div> </div>
<template v-slot:tooltip> <template #tooltip>
<div <div
class="filter-options" class="filter-options"
@click.stop @click.stop
@@ -70,7 +70,7 @@
<script> <script>
function getNewRange(tag) { function getNewRange(tag) {
if (this.selectedTags.includes(tag)) { if (this.selectedTags.includes(tag)) {
return { tags: this.selectedTags.filter(selectedTag => selectedTag !== tag).join(',') || undefined }; return { tags: this.selectedTags.filter((selectedTag) => selectedTag !== tag).join(',') || undefined };
} }
return { tags: this.selectedTags.concat(tag).join(',') }; return { tags: this.selectedTags.concat(tag).join(',') };
@@ -82,10 +82,6 @@ function selectedTags() {
export default { export default {
props: { props: {
filter: {
type: Array,
default: () => [],
},
compact: { compact: {
type: Boolean, type: Boolean,
default: false, default: false,

View File

@@ -8,9 +8,13 @@
:items-total="totalCount" :items-total="totalCount"
:items-per-page="limit" :items-per-page="limit"
:content="$refs.content" :content="$refs.content"
:show-total="false"
/> />
<Releases :releases="releases" /> <Releases
:releases="releases"
:done="done"
/>
<Pagination <Pagination
v-if="totalCount > 0" v-if="totalCount > 0"
@@ -30,6 +34,8 @@ import Releases from '../releases/releases.vue';
import Pagination from '../pagination/pagination.vue'; import Pagination from '../pagination/pagination.vue';
async function fetchReleases(scroll = true) { async function fetchReleases(scroll = true) {
this.done = false;
const { releases, totalCount } = await this.$store.dispatch('fetchReleases', { const { releases, totalCount } = await this.$store.dispatch('fetchReleases', {
limit: this.limit, limit: this.limit,
range: this.$route.params.range, range: this.$route.params.range,
@@ -38,6 +44,7 @@ async function fetchReleases(scroll = true) {
this.totalCount = totalCount; this.totalCount = totalCount;
this.releases = releases; this.releases = releases;
this.done = true;
if (scroll) { if (scroll) {
this.$refs.filter?.$el.scrollIntoView(); this.$refs.filter?.$el.scrollIntoView();
@@ -64,6 +71,7 @@ export default {
limit: 30, limit: 30,
totalCount: 0, totalCount: 0,
from: null, from: null,
done: false,
}; };
}, },
watch: { watch: {

View File

@@ -0,0 +1,90 @@
<template>
<div class="load-container">
<div class="load-ellipsis">
<div />
<div />
<div />
<div />
</div>
</div>
</template>
<style lang="scss" scoped>
.load-container {
display: inline-flex;
position: relative;
padding: 1rem;
}
.load-ellipsis {
display: inline-block;
position: relative;
width: 5rem;
height: .75rem;
}
.load-ellipsis div {
position: absolute;
top: 0;
width: .75rem;
height: .75rem;
border-radius: 50%;
background: var(--primary);
}
.load-ellipsis div:nth-child(1) {
left: .5rem;
animation: load-ellipsis1 0.5s infinite linear;
}
.load-ellipsis div:nth-child(2) {
left: .5rem;
animation: load-ellipsis2 0.5s infinite linear;
}
.load-ellipsis div:nth-child(3) {
left: 2rem;
animation: load-ellipsis3 0.5s infinite linear;
}
.load-ellipsis div:nth-child(4) {
left: 3.5rem;
animation: load-ellipsis4 0.5s infinite linear;
}
@keyframes load-ellipsis1 {
0% {
transform: scale(0);
}
100% {
transform: scale(0.5);
}
}
@keyframes load-ellipsis2 {
0% {
transform: translate(0, 0) scale(0.5);
}
100% {
transform: translate(1.5rem, 0) scale(1);
}
}
@keyframes load-ellipsis3 {
0% {
transform: translate(0, 0) scale(1);
}
100% {
transform: translate(1.5rem, 0) scale(0.5);
}
}
@keyframes load-ellipsis4 {
0% {
transform: scale(0.5);
}
100% {
transform: scale(0);
}
}
</style>

View File

@@ -38,15 +38,30 @@
class="item trailer" class="item trailer"
> >
<a <span
v-if="release.poster" v-if="release.poster || release.teaser"
v-tooltip="'View poster'" class="poster-links"
:href="getPath(release.poster)" >
:class="{ playing }" <a
target="_blank" v-if="release.teaser"
rel="noopener noreferrer" v-tooltip="'View teaser'"
class="poster-link" :href="getPath(release.teaser)"
><Icon icon="image" /></a> :class="{ playing }"
target="_blank"
rel="noopener noreferrer"
class="poster-link"
><Icon icon="film4" /></a>
<a
v-if="release.poster"
v-tooltip="'View poster'"
:href="getPath(release.poster)"
:class="{ playing }"
target="_blank"
rel="noopener noreferrer"
class="poster-link"
><Icon icon="image" /></a>
</span>
<span <span
v-if="sfw && !playing" v-if="sfw && !playing"
@@ -217,11 +232,16 @@ export default {
margin: 0 auto; margin: 0 auto;
} }
.poster-link { .poster-links {
display: flex;
position: absolute; position: absolute;
top: .5rem; top: 0;
right: .5rem; right: 0;
}
.poster-link {
transition: opacity .1s ease; transition: opacity .1s ease;
padding: .5rem;
.icon { .icon {
width: 1.5rem; width: 1.5rem;
@@ -234,6 +254,14 @@ export default {
opacity: 0; opacity: 0;
} }
&:first-child {
padding-left: .75rem;
}
&:last-child {
padding-right: .75rem;
}
&:hover { &:hover {
cursor: pointer; cursor: pointer;
opacity: 1; opacity: 1;

View File

@@ -14,6 +14,12 @@
loading="lazy" loading="lazy"
> >
<div
v-else
:title="movie.title"
class="unavailable"
><Icon icon="blocked" /></div>
<Icon <Icon
v-show="(!stash || stash.primary) && favorited" v-show="(!stash || stash.primary) && favorited"
icon="heart7" icon="heart7"
@@ -161,7 +167,6 @@ export default {
} }
.movie { .movie {
height: 16rem;
display: flex; display: flex;
} }
@@ -171,18 +176,30 @@ export default {
} }
.cover { .cover {
height: 100%; height: 16rem;
width: 11.25rem;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
position: relative; position: relative;
box-shadow: 0 0 3px var(--darken-weak); box-shadow: 0 0 3px var(--darken-weak);
background-color: var(--shadow-hint);
img { img {
height: 100%; height: 100%;
max-width: 12rem; width: 100%;
background-position: center; background-position: center;
background-size: cover; background-size: cover;
object-fit: cover; object-fit: cover;
object-position: center; object-position: center;
} }
.unavailable .icon {
width: 2rem;
height: 2rem;
fill: var(--shadow-hint);
}
} }
.info { .info {
@@ -252,12 +269,12 @@ export default {
} }
.stash { .stash {
width: 1.25rem; width: 1.5rem;
height: 1.25rem; height: 1.5rem;
padding: .25rem .5rem .5rem .25rem; padding: .25rem .5rem .5rem .5rem;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; left: 0;
fill: var(--lighten-weak); fill: var(--lighten-weak);
filter: drop-shadow(0 0 2px var(--darken)); filter: drop-shadow(0 0 2px var(--darken));
@@ -273,8 +290,9 @@ export default {
} }
@media(max-width: $breakpoint-kilo) { @media(max-width: $breakpoint-kilo) {
.movie { .cover {
height: 12rem; height: 12rem;
width: 8.25rem;
} }
/* ensure no half actor names show */ /* ensure no half actor names show */

View File

@@ -3,6 +3,12 @@
<div class="content-inner"> <div class="content-inner">
<SearchBar :placeholder="`Search ${totalCount} movies`" /> <SearchBar :placeholder="`Search ${totalCount} movies`" />
<TagFilter
class="filters-filter"
:filter="filter"
:available-tags="availableTags"
/>
<div <div
ref="tiles" ref="tiles"
class="tiles" class="tiles"
@@ -30,6 +36,7 @@
import MovieTile from './movie-tile.vue'; import MovieTile from './movie-tile.vue';
import SearchBar from '../search/bar.vue'; import SearchBar from '../search/bar.vue';
import Pagination from '../pagination/pagination.vue'; import Pagination from '../pagination/pagination.vue';
import TagFilter from '../filters/tag-filter.vue';
async function fetchMovies() { async function fetchMovies() {
if (this.$route.query.query) { if (this.$route.query.query) {
@@ -73,6 +80,7 @@ export default {
MovieTile, MovieTile,
SearchBar, SearchBar,
Pagination, Pagination,
TagFilter,
}, },
data() { data() {
return { return {

View File

@@ -278,7 +278,7 @@ function bannerBackground() {
function pageTitle() { function pageTitle() {
return this.release return this.release
&& (this.release.title && (this.release.title
|| (this.release.actors.length > 0 ? `${this.release.actors.map(actor => actor.name).join(', ')} for ${this.release.entity.name}` : null)); || (this.release.actors.length > 0 ? `${this.release.actors.map((actor) => actor.name).join(', ')} for ${this.release.entity.name}` : null));
} }
function showAlbum() { function showAlbum() {

View File

@@ -5,8 +5,10 @@
class="heading" class="heading"
><span class="range">{{ range }}</span> releases for '{{ context }}'</h3> ><span class="range">{{ range }}</span> releases for '{{ context }}'</h3>
<Ellipsis v-if="!done" />
<ul <ul
v-if="releases.length > 0" v-else-if="releases.length > 0"
:key="sfw" :key="sfw"
class="nolist tiles" class="nolist tiles"
> >
@@ -25,7 +27,7 @@
</ul> </ul>
<span <span
v-if="releases.length === 0 && range !== 'all'" v-else-if="releases.length === 0 && range !== 'all'"
class="empty" class="empty"
>No {{ range }} releases</span> >No {{ range }} releases</span>
@@ -37,6 +39,7 @@
</template> </template>
<script> <script>
import Ellipsis from '../loading/ellipsis.vue';
import SceneTile from './scene-tile.vue'; import SceneTile from './scene-tile.vue';
function range() { function range() {
@@ -49,6 +52,7 @@ function sfw() {
export default { export default {
components: { components: {
Ellipsis,
SceneTile, SceneTile,
}, },
props: { props: {
@@ -60,6 +64,10 @@ export default {
type: String, type: String,
default: null, default: null,
}, },
done: {
type: Boolean,
default: true,
},
referer: { referer: {
type: String, type: String,
default: null, default: null,
@@ -118,10 +126,29 @@ export default {
font-weight: bold; font-weight: bold;
} }
@media(max-width: $breakpoint-mega) {
.tiles {
grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}
}
@media(max-width: $breakpoint-kilo) { @media(max-width: $breakpoint-kilo) {
.tiles { .tiles {
grid-template-columns: repeat(auto-fill, minmax(18.5rem, 1fr));
grid-gap: .5rem; grid-gap: .5rem;
padding: .5rem; padding: .5rem;
} }
} }
@media(max-width: $breakpoint) {
.tiles {
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
}
}
@media(max-width: $breakpoint-micro) {
.tiles {
grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
}
}
</style> </style>

View File

@@ -113,21 +113,22 @@
:key="actor.id" :key="actor.id"
class="actor" class="actor"
> >
<router-link <RouterLink
:to="{ name: 'actor', params: { actorId: actor.id, actorSlug: actor.slug } }" :to="{ name: 'actor', params: { actorId: actor.id, actorSlug: actor.slug } }"
:class="{ [actor.gender]: !!actor.gender }"
class="actor-link" class="actor-link"
>{{ actor.name }}</router-link> >{{ actor.name }}</RouterLink>
</li> </li>
</ul> </ul>
</span> </span>
<div class="labels"> <div class="labels">
<router-link <RouterLink
v-if="release.shootId && release.studio" v-if="release.shootId && release.studio"
:to="`/studio/${release.studio.slug}`" :to="`/studio/${release.studio.slug}`"
:title="release.studio && release.studio.name" :title="release.studio && release.studio.name"
class="shoot nolink" class="shoot nolink"
>{{ release.shootId }}</router-link> >{{ release.shootId }}</RouterLink>
<span <span
v-else-if="release.shootId" v-else-if="release.shootId"
@@ -145,10 +146,10 @@
:key="`tag-${tag.slug}`" :key="`tag-${tag.slug}`"
class="tag" class="tag"
> >
<router-link <RouterLink
:to="`/tag/${tag.slug}`" :to="`/tag/${tag.slug}`"
class="tag-link" class="tag-link"
>{{ tag.name }}</router-link> >{{ tag.name }}</RouterLink>
</li> </li>
</ul> </ul>
</div> </div>
@@ -233,20 +234,23 @@ export default {
box-shadow: 0 0 3px var(--darken-weak); box-shadow: 0 0 3px var(--darken-weak);
&.new .poster::after { &.new .poster::after {
content: ''; content: 'new';
position: absolute; position: absolute;
top: 0; display: flex;
left: 0; align-items: center;
width: 1rem; justify-content: center;
height: 1rem; bottom: 0;
right: .5rem;
width: 2rem;
box-sizing: border-box; box-sizing: border-box;
margin: .25rem; padding: .1rem 0 .05rem 0;
border-radius: 0 0 .5rem 0; border-radius: .25rem .25rem 0 0;
color: var(--primary); background: var(--info);
font-size: 1rem; color: var(--text-light);
font-size: .7rem;
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
text-shadow: 0 0 2px var(--darken-weak); box-shadow: 0 0 3px var(--shadow);
} }
&:hover .unstashed, &:hover .unstashed,
@@ -295,8 +299,8 @@ export default {
} }
.stash { .stash {
width: 1.25rem; width: 1.5rem;
height: 1.25rem; height: 1.5rem;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
@@ -317,17 +321,18 @@ export default {
} }
.row { .row {
max-width: 100%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: 0 .5rem; padding: 0 .5rem;
margin: 0 0 .1rem 0;
} }
.info { .info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start;
flex-grow: 1; flex-grow: 1;
overflow: hidden; overflow: hidden;
} }
@@ -339,7 +344,7 @@ export default {
.title { .title {
margin: 0; margin: 0;
color: var(--text); color: var(--text);
font-size: 1rem; font-size: .9rem;
line-height: 1.5; line-height: 1.5;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -365,8 +370,9 @@ export default {
} }
.actor-link { .actor-link {
color: var(--link); color: var(--text);
text-decoration: none; text-decoration: none;
font-size: .9rem;
&:hover { &:hover {
color: var(--primary); color: var(--primary);
@@ -374,7 +380,7 @@ export default {
} }
.labels { .labels {
padding: 0 .5rem 1.5rem .5rem; padding: 0 .5rem 1.25rem .5rem;
max-height: .5rem; max-height: .5rem;
overflow-y: hidden; overflow-y: hidden;
font-size: 0; font-size: 0;
@@ -405,11 +411,11 @@ export default {
} }
.tag-link { .tag-link {
background: var(--background); background: var(--shadow-touch);
color: var(--shadow); color: var(--shadow);
display: inline-block; display: inline-block;
padding: .25rem .5rem; padding: .25rem .5rem;
border: solid 1px var(--shadow-hint); margin: 0 1px 0 0;
font-size: .75rem; font-size: .75rem;
font-weight: bold; font-weight: bold;
text-decoration: none; text-decoration: none;
@@ -421,14 +427,20 @@ export default {
} }
.details-wide { .details-wide {
margin: 0 0 .5rem 0; margin: 0 0 .4rem 0;
} }
.details-compact { .details-compact {
display: none; display: none;
} }
@media(max-width: $breakpoint-kilo) { @media(max-width: $breakpoint) {
.thumbnail {
height: 11rem;
}
}
@media(max-width: $breakpoint-micro) {
.tile-body { .tile-body {
flex-direction: row; flex-direction: row;
} }
@@ -474,14 +486,15 @@ export default {
} }
.tile.new .poster::after { .tile.new .poster::after {
bottom: 0; top: 0;
top: auto; right: .25rem;
margin: .1rem .25rem; bottom: auto;
border-radius: 0 0 .25rem .25rem;
padding: .05rem 0 .1rem 0;
} }
.stash { .stash {
left: 0; left: 0;
right: auto;
padding: .25rem .5rem .5rem .25rem; padding: .25rem .5rem .5rem .25rem;
} }
} }

View File

@@ -57,10 +57,7 @@
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
class="date" class="date"
><Icon >{{ formatDate(release.date, 'MMMM D, YYYY', release.datePrecision) }}</a>
v-if="release.url"
icon="share2"
/>{{ formatDate(release.date, 'MMMM D, YYYY', release.datePrecision) }}</a>
<a <a
v-else v-else
@@ -91,27 +88,17 @@ export default {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
z-index: 1;
white-space: nowrap; white-space: nowrap;
background: var(--profile); background: var(--info);
font-size: 0; font-size: 0;
font-weight: bold; font-weight: bold;
.favicon { .favicon {
width: 2rem; width: 2rem;
box-sizing: border-box; box-sizing: border-box;
padding: .5rem; padding: .4rem .5rem;
} }
/*
&.new .date::before {
content: '';
width: .5rem;
height: .5rem;
border-radius: 50%;
margin: 0 .25rem 0 0;
background: var(--primary);
}
*/
} }
.site, .site,
@@ -120,7 +107,7 @@ export default {
align-items: center; align-items: center;
position: relative; position: relative;
font-size: .8rem; font-size: .8rem;
padding: .5rem; padding: .4rem .5rem;
color: var(--text-light); color: var(--text-light);
text-decoration: none; text-decoration: none;

View File

@@ -64,7 +64,10 @@
:fetch-releases="fetchReleases" :fetch-releases="fetchReleases"
/> />
<Releases :releases="releases" /> <Releases
:releases="releases"
:done="done"
/>
<Pagination <Pagination
:items-total="totalCount" :items-total="totalCount"
@@ -93,6 +96,8 @@ import Campaign from '../campaigns/campaign.vue';
const converter = new Converter(); const converter = new Converter();
async function fetchReleases(scroll = true) { async function fetchReleases(scroll = true) {
this.done = false;
const { tag, releases, totalCount } = await this.$store.dispatch('fetchTagBySlug', { const { tag, releases, totalCount } = await this.$store.dispatch('fetchTagBySlug', {
tagSlug: this.$route.params.tagSlug, tagSlug: this.$route.params.tagSlug,
pageNumber: Number(this.$route.params.pageNumber), pageNumber: Number(this.$route.params.pageNumber),
@@ -107,6 +112,8 @@ async function fetchReleases(scroll = true) {
this.hasMedia = this.tag.poster || this.tag.photos.length > 0; this.hasMedia = this.tag.poster || this.tag.photos.length > 0;
this.description = this.tag.description && converter.makeHtml(escapeHtml(this.tag.description)); this.description = this.tag.description && converter.makeHtml(escapeHtml(this.tag.description));
this.done = true;
if (this.hasMedia) { if (this.hasMedia) {
this.showBannerCampaign = true; this.showBannerCampaign = true;
} }
@@ -146,6 +153,7 @@ export default {
tag: null, tag: null,
description: null, description: null,
releases: null, releases: null,
done: false,
totalCount: 0, totalCount: 0,
limit: 20, limit: 20,
pageTitle: null, pageTitle: null,

View File

@@ -1,7 +1,10 @@
<template> <template>
<div class="tags"> <div class="tags">
<div class="content-inner"> <div class="content-inner">
<SearchBar :placeholder="'Search tags'" /> <SearchBar
:placeholder="'Search tags'"
class="search"
/>
<div <div
v-for="(tags, category) in categories" v-for="(tags, category) in categories"
@@ -42,6 +45,8 @@ const tagSlugsByCategory = {
'teen', 'teen',
'milf', 'milf',
'blowjob', 'blowjob',
'gay',
'transsexual',
'dp', 'dp',
'gangbang', 'gangbang',
'facial', 'facial',
@@ -61,14 +66,18 @@ const tagSlugsByCategory = {
'tattoos', 'tattoos',
'piercings', 'piercings',
], ],
sexuality: [
'gay',
'bisexual',
'transsexual',
],
oral: [ oral: [
'blowjob', 'blowjob',
'pussy-eating', 'pussy-eating',
'ass-eating', 'ass-eating',
'69',
'double-blowjob',
'deepthroat', 'deepthroat',
'facefucking', 'facefucking',
'69',
'atm', 'atm',
], ],
manual: [ manual: [
@@ -89,7 +98,6 @@ const tagSlugsByCategory = {
], ],
cumshot: [ cumshot: [
'facial', 'facial',
'bukkake',
'creampie', 'creampie',
'cum-in-mouth', 'cum-in-mouth',
'cum-on-boobs', 'cum-on-boobs',
@@ -97,6 +105,7 @@ const tagSlugsByCategory = {
'cum-on-pussy', 'cum-on-pussy',
'anal-creampie', 'anal-creampie',
'oral-creampie', 'oral-creampie',
'bukkake',
'fake-cum', 'fake-cum',
], ],
toys: [ toys: [
@@ -121,6 +130,7 @@ const tagSlugsByCategory = {
'bdsm', 'bdsm',
'femdom', 'femdom',
'bondage', 'bondage',
'free-use',
'latex', 'latex',
'blindfold', 'blindfold',
], ],
@@ -159,10 +169,18 @@ async function fetchTags() {
const tagsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag }), {}); const tagsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag }), {});
this.categories = Object.entries(tagSlugsByCategory).reduce((acc, [category, tagSlugs]) => ({ this.categories = Object.entries(tagSlugsByCategory).reduce((acc, [category, tagSlugs]) => {
...acc, const categoryTags = tagSlugs.map((tagSlug) => tagsBySlug[tagSlug]).filter(Boolean);
[category]: tagSlugs.map(tagSlug => tagsBySlug[tagSlug]),
}), {}); if (categoryTags.length === 0) {
return acc;
}
return {
...acc,
[category]: categoryTags,
};
}, {});
} }
async function searchTags() { async function searchTags() {
@@ -199,6 +217,7 @@ export default {
}, },
watch: { watch: {
$route: fetchTags, $route: fetchTags,
'$store.state.ui.tagFilter': fetchTags,
}, },
mounted, mounted,
methods: { methods: {
@@ -209,7 +228,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import 'theme'; @import 'breakpoints';
.tags { .tags {
display: flex; display: flex;
@@ -225,35 +244,97 @@ export default {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(20rem, .33fr)); grid-template-columns: repeat(auto-fill, minmax(20rem, .33fr));
grid-gap: 1rem; grid-gap: 1rem;
margin: 0 0 1.5rem 0;
} }
.heading { .heading {
text-transform: capitalize; text-transform: capitalize;
padding: 0 0 0 .5rem; padding: 0 0 0 .5rem;
margin: 1.75rem 0 1rem 0; margin: 1.25rem 0 1rem 0;
} }
.category:first-child .heading { .category:first-child .heading {
margin: .5rem 0 1rem 0; margin: .5rem 0 1rem 0;
} }
@media(max-width: $breakpoint3) { .search {
margin: 0 0 .25rem 0;
}
@media(max-width: $breakpoint-mega) {
.tiles { .tiles {
grid-template-columns: repeat(auto-fill, minmax(18rem, .5fr)); grid-template-columns: repeat(auto-fill, minmax(17.75rem, .5fr));
} }
::v-deep(.poster),
::v-deep(.blank) {
height: 12rem;
}
}
@media(max-width: $breakpoint-kilo) {
.tiles {
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
grid-gap: .5rem;
}
::v-deep(.poster),
::v-deep(.blank) {
height: 14rem;
}
} }
@media(max-width: $breakpoint) { @media(max-width: $breakpoint) {
.tiles { .tiles {
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(14.5rem, 1fr));
grid-gap: .5rem; grid-gap: .5rem;
} }
::v-deep(.poster),
::v-deep(.blank) {
height: 11rem;
}
} }
@media(max-width: $breakpoint0) { @media(max-width: $breakpoint-small) {
::v-deep(.poster),
::v-deep(.blank) {
height: 10rem;
}
}
@media(max-width: $breakpoint-micro) {
.tiles { .tiles {
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
} }
::v-deep(.poster),
::v-deep(.blank) {
height: 7.5rem;
}
}
@media(max-width: $breakpoint-mini) {
.tiles {
grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
}
::v-deep(.poster),
::v-deep(.blank) {
height: 12rem;
}
}
@media(max-width: $breakpoint-nano) {
::v-deep(.poster),
::v-deep(.blank) {
height: 10rem;
}
}
@media(max-width: $breakpoint-pico) {
::v-deep(.poster),
::v-deep(.blank) {
height: 8rem;
}
} }
</style> </style>

View File

@@ -44,6 +44,11 @@
&:hover { &:hover {
background: var(--primary-strong); background: var(--primary-strong);
} }
&:disabled {
background: var(--shadow-weak);
cursor: default;
}
} }
.button-secondary { .button-secondary {

View File

@@ -5,10 +5,17 @@ $breakpoint3: 1200px;
$breakpoint4: 1500px; $breakpoint4: 1500px;
:root { :root {
--primary: #f65596;
--primary-strong: #f90071;
--primary-faded: #ffcce4;
/*
--primary: #f04288;
--primary: #ff6c88; --primary: #ff6c88;
--primary-strong: #ff4166; --primary-strong: #ff4166;
--primary-faded: #ffdfee; --primary-faded: #ffdfee;
/*
--primary: #f28; --primary: #f28;
--primary-strong: #f90071; --primary-strong: #f90071;
--primary-faded: #ffcce4; --primary-faded: #ffcce4;
@@ -39,6 +46,8 @@ $breakpoint4: 1500px;
--logo-shadow: drop-shadow(1px 0 0 $shadow-weak) drop-shadow(-1px 0 0 $shadow-weak) drop-shadow(0 1px 0 $shadow-weak) drop-shadow(0 -1px 0 $shadow-weak); --logo-shadow: drop-shadow(1px 0 0 $shadow-weak) drop-shadow(-1px 0 0 $shadow-weak) drop-shadow(0 1px 0 $shadow-weak) drop-shadow(0 -1px 0 $shadow-weak);
--logo-highlight: drop-shadow(0 0 1px $highlight); --logo-highlight: drop-shadow(0 0 1px $highlight);
--info: #321b24;
--male: #0af; --male: #0af;
--female: #f0a; --female: #f0a;

View File

@@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>film4</title>
<path d="M0 2v12h16v-12h-16zM3 13h-2v-2h2v2zM3 9h-2v-2h2v2zM3 5h-2v-2h2v2zM12 13h-8v-10h8v10zM15 13h-2v-2h2v2zM15 9h-2v-2h2v2zM15 5h-2v-2h2v2zM6 5v6l4-3z"></path>
</svg>

After

Width:  |  Height:  |  Size: 322 B

View File

@@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>presentation</title>
<path d="M14.25 0h-13.5c-0.412 0-0.75 0.338-0.75 0.75v11.5c0 0.412 0.338 0.75 0.75 0.75h4.455l-2.040 2.040c-0.22 0.22-0.22 0.576 0 0.795 0.11 0.11 0.254 0.165 0.398 0.165s0.288-0.055 0.398-0.165l2.835-2.835h0.205v2.5c0 0.276 0.224 0.5 0.5 0.5s0.5-0.224 0.5-0.5v-2.5h0.205l2.835 2.835c0.11 0.11 0.254 0.165 0.398 0.165s0.288-0.055 0.398-0.165c0.22-0.22 0.22-0.576 0-0.795l-2.040-2.040h4.455c0.412 0 0.75-0.338 0.75-0.75v-11.5c0-0.412-0.338-0.75-0.75-0.75zM6 3l4 2.5-4 2.5v-5zM12.5 11h-10c-0.276 0-0.5-0.224-0.5-0.5s0.224-0.5 0.5-0.5h10c0.276 0 0.5 0.224 0.5 0.5s-0.224 0.5-0.5 0.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 756 B

View File

@@ -281,7 +281,7 @@ function initActorActions(store, router) {
return { return {
actor: curateActor(actor, null, curateRelease), actor: curateActor(actor, null, curateRelease),
releases: actor.scenesConnection.releases.map(release => curateRelease(release)), releases: actor.scenesConnection.releases.map((release) => curateRelease(release)),
totalCount: actor.scenesConnection.totalCount, totalCount: actor.scenesConnection.totalCount,
}; };
} }
@@ -303,7 +303,8 @@ function initActorActions(store, router) {
const genderFilter = (gender === null && 'gender: { isNull: true }') const genderFilter = (gender === null && 'gender: { isNull: true }')
|| (gender === 'all' && ' ') || (gender === 'all' && ' ')
|| `gender: { equalTo: "${gender}" }`; || (gender && `gender: { equalTo: "${gender}" }`)
|| '';
const ageFilter = age ? ` const ageFilter = age ? `
or: [ or: [
@@ -422,13 +423,13 @@ function initActorActions(store, router) {
query, query,
offset: Math.max(0, (pageNumber - 1)) * limit, offset: Math.max(0, (pageNumber - 1)) * limit,
limit, limit,
naturalBoobs, naturalBoobs: naturalBoobs || null,
hasAuth: !!store.state.auth.user, hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id, userId: store.state.auth.user?.id,
}); });
return { return {
actors: actors.map(actor => curateActor(actor)), actors: actors.map((actor) => curateActor(actor)),
totalCount, totalCount,
countries, countries,
}; };

View File

@@ -1,5 +1,5 @@
function favoritesStash(state) { function favoritesStash(state) {
return state.user.stashes.find(stash => stash.slug === 'favorites'); return state.user.stashes.find((stash) => stash.slug === 'favorites');
} }
module.exports = { module.exports = {

View File

@@ -31,8 +31,8 @@ function curateActor(actor, release) {
if (actor.profiles) { if (actor.profiles) {
const photos = actor.profiles const photos = actor.profiles
.map(profile => ({ entity: profile.entity, ...profile.avatar })) .map((profile) => ({ entity: profile.entity, ...profile.avatar }))
.filter(avatar => avatar.id && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash)); .filter((avatar) => avatar.id && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash));
const descriptions = actor.profiles.reduce((acc, profile) => ({ const descriptions = actor.profiles.reduce((acc, profile) => ({
...acc, ...acc,
@@ -57,10 +57,10 @@ function curateActor(actor, release) {
} }
if (actor.stashes) { if (actor.stashes) {
curatedActor.stashes = actor.stashes.filter(Boolean).map(stash => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define curatedActor.stashes = actor.stashes.filter(Boolean).map((stash) => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
} }
curatedActor.stashes = actor.stashes?.map(stash => stash.stash || stash) || []; curatedActor.stashes = actor.stashes?.map((stash) => stash.stash || stash) || [];
return curatedActor; return curatedActor;
} }
@@ -70,21 +70,21 @@ function curateRelease(release) {
...release, ...release,
actors: [], actors: [],
poster: release.poster && release.poster.media, poster: release.poster && release.poster.media,
tags: release.tags ? release.tags.map(tag => tag.tag || tag) : [], tags: release.tags ? release.tags.map((tag) => tag.tag || tag) : [],
}; };
if (release.scenes) curatedRelease.scenes = release.scenes.filter(Boolean).map(({ scene }) => curateRelease(scene)); if (release.scenes) curatedRelease.scenes = release.scenes.filter(Boolean).map(({ scene }) => curateRelease(scene));
if (release.movies) curatedRelease.movies = release.movies.filter(Boolean).map(({ movie }) => curateRelease(movie)); if (release.movies) curatedRelease.movies = release.movies.filter(Boolean).map(({ movie }) => curateRelease(movie));
if (release.chapters) curatedRelease.chapters = release.chapters.filter(Boolean).map(chapter => curateRelease(chapter)); if (release.chapters) curatedRelease.chapters = release.chapters.filter(Boolean).map((chapter) => curateRelease(chapter));
if (release.photos) curatedRelease.photos = release.photos.filter(Boolean).map(photo => photo.media || photo); if (release.photos) curatedRelease.photos = release.photos.filter(Boolean).map((photo) => photo.media || photo);
if (release.covers) curatedRelease.covers = release.covers.filter(Boolean).map(({ media }) => media); if (release.covers) curatedRelease.covers = release.covers.filter(Boolean).map(({ media }) => media);
if (release.trailer) curatedRelease.trailer = release.trailer.media; if (release.trailer) curatedRelease.trailer = release.trailer.media;
if (release.teaser) curatedRelease.teaser = release.teaser.media; if (release.teaser) curatedRelease.teaser = release.teaser.media;
if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map(actor => curateActor(actor.actor || actor, curatedRelease)); if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map((actor) => curateActor(actor.actor || actor, curatedRelease));
if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map(director => curateActor(director.director || director, curatedRelease)); if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map((director) => curateActor(director.director || director, curatedRelease));
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag); if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag);
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease)); if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));
if (release.stashes) curatedRelease.stashes = release.stashes.filter(Boolean).map(stash => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define if (release.stashes) curatedRelease.stashes = release.stashes.filter(Boolean).map((stash) => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
if (release.productionLocation) { if (release.productionLocation) {
curatedRelease.productionLocation = { curatedRelease.productionLocation = {
@@ -108,14 +108,16 @@ function curateEntity(entity, parent, releases) {
if (entity.children) { if (entity.children) {
if (entity.children.nodes) { if (entity.children.nodes) {
curatedEntity.children = entity.children.nodes.map(childEntity => curateEntity(childEntity, curatedEntity)); curatedEntity.children = entity.children.nodes.map((childEntity) => curateEntity(childEntity, curatedEntity));
} }
curatedEntity.childrenTotal = entity.children.totalCount; curatedEntity.childrenTotal = entity.children.totalCount;
} }
if (entity.parent || parent) curatedEntity.parent = curateEntity(entity.parent || parent); if (entity.parent || parent) curatedEntity.parent = curateEntity(entity.parent || parent);
if (releases) curatedEntity.releases = releases.map(release => curateRelease(release)); if (releases) curatedEntity.releases = releases.map((release) => curateRelease(release));
curatedEntity.sceneTotal = entity.sceneTotal;
return curatedEntity; return curatedEntity;
} }
@@ -138,7 +140,7 @@ function curateStash(stash) {
if (stash.scenes || stash.scenesConnection?.scenes) { if (stash.scenes || stash.scenesConnection?.scenes) {
curatedStash.sceneTotal = stash.scenesConnection?.totalCount || null; curatedStash.sceneTotal = stash.scenesConnection?.totalCount || null;
curatedStash.scenes = (stash.scenesConnection?.scenes || stash.scenes).map(item => ({ curatedStash.scenes = (stash.scenesConnection?.scenes || stash.scenes).map((item) => ({
...item, ...item,
scene: curateRelease(item.scene), scene: curateRelease(item.scene),
})); }));
@@ -146,7 +148,7 @@ function curateStash(stash) {
if (stash.actors || stash.actorsConnection?.actors) { if (stash.actors || stash.actorsConnection?.actors) {
curatedStash.actorTotal = stash.actorsConnection?.totalCount || null; curatedStash.actorTotal = stash.actorsConnection?.totalCount || null;
curatedStash.actors = (stash.actorsConnection?.actors || stash.actors).map(item => ({ curatedStash.actors = (stash.actorsConnection?.actors || stash.actors).map((item) => ({
...item, ...item,
actor: curateActor(item.actor), actor: curateActor(item.actor),
})); }));
@@ -154,7 +156,7 @@ function curateStash(stash) {
if (stash.movies || stash.moviesConnection?.movies) { if (stash.movies || stash.moviesConnection?.movies) {
curatedStash.movieTotal = stash.moviesConnection?.totalCount || null; curatedStash.movieTotal = stash.moviesConnection?.totalCount || null;
curatedStash.movies = (stash.moviesConnection?.movies || stash.movies).map(item => ({ curatedStash.movies = (stash.moviesConnection?.movies || stash.movies).map((item) => ({
...item, ...item,
movie: curateRelease(item.movie), movie: curateRelease(item.movie),
})); }));
@@ -171,11 +173,11 @@ function curateAlert(alert) {
const curatedAlert = alert; const curatedAlert = alert;
if (alert.actors) { if (alert.actors) {
curatedAlert.actors = alert.actors.map(actor => curateActor(actor.actor || actor)); curatedAlert.actors = alert.actors.map((actor) => curateActor(actor.actor || actor));
} }
if (alert.tags) { if (alert.tags) {
curatedAlert.tags = alert.tags.map(tag => curateTag(tag.tag || tag)); curatedAlert.tags = alert.tags.map((tag) => curateTag(tag.tag || tag));
} }
if (alert.entity) { if (alert.entity) {
@@ -183,7 +185,7 @@ function curateAlert(alert) {
} }
if (alert.stashes) { if (alert.stashes) {
curatedAlert.stashes = alert.stashes.map(stash => curateStash(stash.stash || stash)); curatedAlert.stashes = alert.stashes.map((stash) => curateStash(stash.stash || stash));
} }
return curatedAlert; return curatedAlert;
@@ -197,11 +199,11 @@ function curateUser(user) {
const curatedUser = user; const curatedUser = user;
if (user.stashes) { if (user.stashes) {
curatedUser.stashes = user.stashes.map(stash => curateStash(stash.stash || stash)); curatedUser.stashes = user.stashes.map((stash) => curateStash(stash.stash || stash));
} }
if (user.alerts) { if (user.alerts) {
curatedUser.alerts = user.alerts.map(alert => curateAlert(alert.alert || alert)); curatedUser.alerts = user.alerts.map((alert) => curateAlert(alert.alert || alert));
} }
return curatedUser; return curatedUser;

View File

@@ -14,7 +14,7 @@ function initEntitiesActions(store, router) {
}) { }) {
const { before, after, orderBy } = getDateRange(range); const { before, after, orderBy } = getDateRange(range);
const { entity, connection: { releases, totalCount } } = await graphql(` const { entity } = await graphql(`
query Entity( query Entity(
$entitySlug: String! $entitySlug: String!
$entityType: String! = "channel" $entityType: String! = "channel"
@@ -22,8 +22,6 @@ function initEntitiesActions(store, router) {
$offset: Int = 0, $offset: Int = 0,
$after: Datetime = "1900-01-01", $after: Datetime = "1900-01-01",
$before: Datetime = "2100-01-01", $before: Datetime = "2100-01-01",
$afterTime: Datetime = "1900-01-01",
$beforeTime: Datetime = "2100-01-01",
$orderBy: [ReleasesOrderBy!] $orderBy: [ReleasesOrderBy!]
$exclude: [String!] $exclude: [String!]
$hasAuth: Boolean! $hasAuth: Boolean!
@@ -64,6 +62,10 @@ function initEntitiesActions(store, router) {
independent independent
hasLogo hasLogo
${campaignsFragment} ${campaignsFragment}
sceneTotal
children: childEntitiesConnection {
totalCount
}
} }
} }
${campaignsFragment} ${campaignsFragment}
@@ -77,82 +79,44 @@ function initEntitiesActions(store, router) {
hasLogo hasLogo
${campaignsFragment} ${campaignsFragment}
} }
} connection: scenesConnection(
connection: releasesConnection( first: $limit
first: $limit offset: $offset
offset: $offset orderBy: $orderBy
orderBy: $orderBy filter: {
filter: { or: [
and: [ {
{ date: {
entity: { isNull: ${entityType !== 'network'}
or: [
{
slug: { equalTo: $entitySlug }
},
{
parent: {
slug: { equalTo: $entitySlug }
type: { equalTo: $entityType }
}
},
{
parent: {
parent: {
slug: { equalTo: $entitySlug }
type: { equalTo: $entityType }
}
}
}
{
parent: {
parent: {
parent: {
slug: { equalTo: $entitySlug }
type: { equalTo: $entityType }
}
},
},
},
]
}
}
{
or: [
{
date: {
lessThan: $before,
greaterThan: $after
}
},
{
date: {
isNull: true
},
createdAt: {
lessThan: $beforeTime,
greaterThan: $afterTime,
}
} }
] }
{
date: {
isNull: false
}
}
]
date: {
lessThan: $before,
greaterThan: $after
} }
] releasesTagsConnection: {
releasesTagsConnection: { none: {
none: { tag: {
tag: { slug: {
slug: { in: $exclude
in: $exclude }
} }
} }
} }
} }
) {
releases: nodes {
${releaseFields}
}
totalCount
} }
) { }
releases: nodes {
${releaseFields}
}
totalCount
}
} }
`, { `, {
entitySlug, entitySlug,
@@ -162,8 +126,6 @@ function initEntitiesActions(store, router) {
after, after,
before, before,
orderBy, orderBy,
afterTime: store.getters.after,
beforeTime: store.getters.before,
exclude: store.state.ui.tagFilter, exclude: store.state.ui.tagFilter,
hasAuth: !!store.state.auth.user, hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id, userId: store.state.auth.user?.id,
@@ -175,8 +137,8 @@ function initEntitiesActions(store, router) {
} }
return { return {
entity: curateEntity(entity, null, releases), entity: curateEntity(entity, null, entity.connection.releases),
totalCount, totalCount: entity.connection.totalCount,
}; };
} }
@@ -240,17 +202,17 @@ function initEntitiesActions(store, router) {
entitySlugs, entitySlugs,
}); });
return entities.map(entity => curateEntity(entity)); return entities.map((entity) => curateEntity(entity));
} }
async function searchEntities({ _commit }, { query, limit = 20 }) { async function searchEntities({ _commit }, { query, limit = 20 }) {
const { entities } = await graphql(` const { entities } = await graphql(`
query SearchEntities( query SearchEntities(
$query: String! $query: String!
$limit:Int = 20, $limit: Int = 20,
) { ) {
entities: searchEntities( entities: searchEntities(
search: $query, search: $query
first: $limit first: $limit
) { ) {
id id
@@ -274,7 +236,7 @@ function initEntitiesActions(store, router) {
limit, limit,
}); });
return entities.map(entity => curateEntity(entity)); return entities.map((entity) => curateEntity(entity));
} }
return { return {

View File

@@ -5,7 +5,7 @@ export function formatDuration(duration, forceHours) {
const minutes = Math.floor((duration % 3600) / 60); const minutes = Math.floor((duration % 3600) / 60);
const seconds = Math.floor(duration % 60); const seconds = Math.floor(duration % 60);
const [formattedHours, formattedMinutes, formattedSeconds] = [hours, minutes, seconds].map(segment => segment.toString().padStart(2, '0')); const [formattedHours, formattedMinutes, formattedSeconds] = [hours, minutes, seconds].map((segment) => segment.toString().padStart(2, '0'));
if (duration >= 3600 || forceHours) { if (duration >= 3600 || forceHours) {
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`; return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;

View File

@@ -125,7 +125,7 @@ const movieFields = `
type type
} }
} }
covers: moviesCovers { covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
media { media {
id id
path path
@@ -244,7 +244,12 @@ const releaseDirectorFragment = `
`; `;
const releaseTagsFragment = ` const releaseTagsFragment = `
tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) { tags: releasesTags(
orderBy: TAG_BY_TAG_ID__PRIORITY_DESC
filter: {
tagId: { isNull: false }
}
) {
tag { tag {
name name
priority priority
@@ -255,7 +260,7 @@ const releaseTagsFragment = `
`; `;
const releasePosterFragment = ` const releasePosterFragment = `
poster: releasesPosterByReleaseId { poster: releasesPoster {
media { media {
id id
index index
@@ -330,7 +335,7 @@ const releasePhotosFragment = `
`; `;
const releaseTrailerFragment = ` const releaseTrailerFragment = `
trailer: releasesTrailerByReleaseId { trailer: releasesTrailer {
media { media {
id id
index index
@@ -344,7 +349,7 @@ const releaseTrailerFragment = `
`; `;
const releaseTeaserFragment = ` const releaseTeaserFragment = `
teaser: releasesTeaserByReleaseId { teaser: releasesTeaser {
media { media {
id id
index index
@@ -482,7 +487,7 @@ const releaseFragment = `
slug slug
} }
} }
poster: chaptersPosterByChapterId { poster: chaptersPoster {
media { media {
id id
index index
@@ -511,7 +516,7 @@ const releaseFragment = `
id id
title title
slug slug
covers: moviesCovers { covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
media { media {
id id
index index

View File

@@ -7,12 +7,12 @@ const dateRanges = {
latest: () => ({ latest: () => ({
after: '1900-01-01', after: '1900-01-01',
before: dayjs.utc().toDate(), before: dayjs.utc().toDate(),
orderBy: ['DATE_DESC', 'CREATED_AT_DESC'], orderBy: ['DATE_DESC'],
}), }),
upcoming: () => ({ upcoming: () => ({
after: dayjs.utc().toDate(), after: dayjs.utc().toDate(),
before: '2100-01-01', before: '2100-01-01',
orderBy: ['DATE_ASC', 'CREATED_AT_ASC'], orderBy: ['DATE_DESC'],
}), }),
new: () => ({ new: () => ({
after: '1900-01-01 00:00:00', after: '1900-01-01 00:00:00',
@@ -22,35 +22,10 @@ const dateRanges = {
all: () => ({ all: () => ({
after: '1900-01-01', after: '1900-01-01',
before: '2100-01-01', before: '2100-01-01',
orderBy: ['DATE_DESC', 'CREATED_AT_DESC'], orderBy: ['DATE_DESC'],
}), }),
}; };
/* requires PostgreSQL 12.x> not available in production yet
const dateRanges = {
latest: () => ({
after: '1900-01-01',
before: dayjs.utc().toDate(),
orderBy: ['EFFECTIVE_DATE_DESC'],
}),
upcoming: () => ({
after: dayjs.utc().toDate(),
before: '2100-01-01',
orderBy: ['EFFECTIVE_DATE_DESC'],
}),
new: () => ({
after: '1900-01-01 00:00:00',
before: '2100-01-01',
orderBy: ['CREATED_AT_DESC', 'EFFECTIVE_DATE_ASC'],
}),
all: () => ({
after: '1900-01-01',
before: '2100-01-01',
orderBy: ['EFFECTIVE_DATE_DESC'],
}),
};
*/
function getDateRange(range) { function getDateRange(range) {
return (dateRanges[range] || dateRanges.all)(); return (dateRanges[range] || dateRanges.all)();
} }

View File

@@ -109,6 +109,10 @@ async function init() {
document.title = 'traxxx'; document.title = 'traxxx';
}, },
}, },
beforeCreate() {
this.uid = uid;
uid += 1;
},
methods: { methods: {
formatDate, formatDate,
formatDuration, formatDuration,
@@ -117,10 +121,6 @@ async function init() {
getPath, getPath,
getBgPath: (media, type) => `url(${getPath(media, type)})`, getBgPath: (media, type) => `url(${getPath(media, type)})`,
}, },
beforeCreate() {
this.uid = uid;
uid += 1;
},
}); });
app.directive('tooltip', { app.directive('tooltip', {

View File

@@ -37,7 +37,7 @@ function initReleasesActions(store, router) {
}); });
return { return {
releases: releases.map(release => curateRelease(release)), releases: releases.map((release) => curateRelease(release)),
totalCount, totalCount,
}; };
} }
@@ -99,7 +99,7 @@ function initReleasesActions(store, router) {
}); });
return { return {
movies: movies.map(release => curateRelease(release)), movies: movies.map((release) => curateRelease(release)),
totalCount, totalCount,
}; };
} }
@@ -110,6 +110,8 @@ function initReleasesActions(store, router) {
$query: String! $query: String!
$limit:Int = 20 $limit:Int = 20
$offset:Int = 0 $offset:Int = 0
$hasAuth: Boolean!
$userId: Int
) { ) {
connection: searchMoviesConnection( connection: searchMoviesConnection(
query: $query query: $query
@@ -126,6 +128,8 @@ function initReleasesActions(store, router) {
} }
} }
`, { `, {
hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id,
query, query,
limit, limit,
offset: Math.max(0, (pageNumber - 1)) * limit, offset: Math.max(0, (pageNumber - 1)) * limit,
@@ -178,7 +182,7 @@ function initReleasesActions(store, router) {
isS3 isS3
} }
} }
poster: moviesPosterByMovieId { poster: moviesPoster {
media { media {
id id
path path
@@ -191,7 +195,7 @@ function initReleasesActions(store, router) {
isS3 isS3
} }
} }
covers: moviesCovers { covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
media { media {
id id
path path
@@ -204,7 +208,7 @@ function initReleasesActions(store, router) {
isS3 isS3
} }
} }
trailer: moviesTrailerByMovieId { trailer: moviesTrailer {
media { media {
id id
path path

View File

@@ -74,7 +74,7 @@ const routes = [
{ {
path: '/actor/:actorId/:actorSlug', path: '/actor/:actorId/:actorSlug',
name: 'actor', name: 'actor',
redirect: from => ({ redirect: (from) => ({
name: 'actorRange', name: 'actorRange',
params: { params: {
...from.params, ...from.params,
@@ -91,7 +91,7 @@ const routes = [
{ {
path: '/director/:actorId/:actorSlug', path: '/director/:actorId/:actorSlug',
name: 'director', name: 'director',
redirect: from => ({ redirect: (from) => ({
name: 'directorRange', name: 'directorRange',
params: { params: {
...from.params, ...from.params,
@@ -107,7 +107,7 @@ const routes = [
}, },
{ {
path: '/channel/:entitySlug', path: '/channel/:entitySlug',
redirect: from => ({ redirect: (from) => ({
name: 'channel', name: 'channel',
params: { params: {
...from.params, ...from.params,
@@ -123,7 +123,7 @@ const routes = [
}, },
{ {
path: '/network/:entitySlug', path: '/network/:entitySlug',
redirect: from => ({ redirect: (from) => ({
name: 'network', name: 'network',
params: { params: {
...from.params, ...from.params,
@@ -139,7 +139,7 @@ const routes = [
}, },
{ {
path: '/studio/:entitySlug', path: '/studio/:entitySlug',
redirect: from => ({ redirect: (from) => ({
name: 'studio', name: 'studio',
params: { params: {
...from.params, ...from.params,
@@ -155,7 +155,7 @@ const routes = [
}, },
{ {
path: '/tag/:tagSlug', path: '/tag/:tagSlug',
redirect: from => ({ redirect: (from) => ({
name: 'tag', name: 'tag',
params: { params: {
...from.params, ...from.params,
@@ -171,7 +171,7 @@ const routes = [
}, },
{ {
path: '/actors', path: '/actors',
redirect: from => ({ redirect: (from) => ({
name: 'actors', name: 'actors',
params: { params: {
...from.params, ...from.params,
@@ -229,7 +229,7 @@ const routes = [
}, },
{ {
path: '/stash/:stashId/:stashSlug', path: '/stash/:stashId/:stashSlug',
redirect: from => ({ redirect: (from) => ({
name: 'stash', name: 'stash',
params: { params: {
...from.params, ...from.params,

View File

@@ -35,7 +35,7 @@ function initTagsActions(store, _router) {
name name
slug slug
} }
poster: tagsPosterByTagId { poster: tagsPoster {
media { media {
id id
thumbnail thumbnail
@@ -188,14 +188,14 @@ function initTagsActions(store, _router) {
before, before,
orderBy, orderBy,
offset: Math.max(0, (pageNumber - 1)) * limit, offset: Math.max(0, (pageNumber - 1)) * limit,
exclude: store.state.ui.tagFilter.filter(tagFilter => tagFilter !== tagSlug), exclude: store.state.ui.tagFilter.filter((tagFilter) => tagFilter !== tagSlug),
hasAuth: !!store.state.auth.user, hasAuth: !!store.state.auth.user,
userId: store.state.auth.user?.id, userId: store.state.auth.user?.id,
}); });
return { return {
tag: curateTag(tagBySlug, null, curateRelease), tag: curateTag(tagBySlug, null, curateRelease),
releases: tagBySlug.scenesConnection.releases.map(release => curateRelease(release)), releases: tagBySlug.scenesConnection.releases.map((release) => curateRelease(release)),
totalCount: tagBySlug.scenesConnection.totalCount, totalCount: tagBySlug.scenesConnection.totalCount,
}; };
} }
@@ -210,15 +210,21 @@ function initTagsActions(store, _router) {
query Tags( query Tags(
$slugs: [String!] = [], $slugs: [String!] = [],
$limit: Int = 100 $limit: Int = 100
$exclude: [String!]
) { ) {
tags( tags(
filter: { slug: { in: $slugs } }, filter: {
slug: {
in: $slugs
notIn: $exclude
}
},
first: $limit first: $limit
) { ) {
id id
name name
slug slug
poster: tagsPosterByTagId { poster: tagsPoster {
media { media {
thumbnail thumbnail
comment comment
@@ -257,9 +263,10 @@ function initTagsActions(store, _router) {
`, { `, {
slugs, slugs,
limit, limit,
exclude: store.state.ui.tagFilter,
}); });
return tags.map(tag => curateTag(tag, store.state.ui.sfw)); return tags.map((tag) => curateTag(tag, store.state.ui.sfw));
} }
async function searchTags({ _commit }, { async function searchTags({ _commit }, {
@@ -283,7 +290,7 @@ function initTagsActions(store, _router) {
id id
name name
slug slug
poster: tagsPosterByTagId { poster: tagsPoster {
media { media {
thumbnail thumbnail
comment comment
@@ -325,7 +332,7 @@ function initTagsActions(store, _router) {
minLength, minLength,
}); });
return tags.map(tag => curateTag(tag, store.state.ui.sfw)); return tags.map((tag) => curateTag(tag, store.state.ui.sfw));
} }
async function fetchTagReleases({ _commit }, tagId) { async function fetchTagReleases({ _commit }, tagId) {

View File

@@ -70,7 +70,7 @@ function initUiActions(store, _router) {
slug slug
} }
} }
entity: alertsEntityByAlertId { entity: alertsEntity {
entity { entity {
id id
name name
@@ -103,7 +103,7 @@ function initUiActions(store, _router) {
}; };
} }
const curatedNotifications = notifications.nodes.map(notification => curateNotification(notification)); const curatedNotifications = notifications.nodes.map((notification) => curateNotification(notification));
return { return {
notifications: curatedNotifications, notifications: curatedNotifications,
@@ -222,8 +222,8 @@ function initUiActions(store, _router) {
}); });
return { return {
releases: res?.results.map(result => curateRelease(result.release)) || [], releases: res?.results.map((result) => curateRelease(result.release)) || [],
actors: res?.actors.map(actor => curateActor(actor)) || [], actors: res?.actors.map((actor) => curateActor(actor)) || [],
}; };
} }

View File

@@ -3,7 +3,7 @@ async function initUiObservers(store, _router) {
body.classList.add(store.state.ui.theme); body.classList.add(store.state.ui.theme);
store.watch(state => state.ui.theme, (newTheme, oldTheme) => { store.watch((state) => state.ui.theme, (newTheme, oldTheme) => {
body.classList.add(newTheme); body.classList.add(newTheme);
body.classList.remove(oldTheme); body.classList.remove(oldTheme);
}); });

View File

@@ -90,7 +90,7 @@ function initUsersActions(store, _router) {
${actorFields} ${actorFields}
} }
} }
entity: alertsEntityByAlertId { entity: alertsEntity {
entity { entity {
id id
name name

View File

@@ -66,10 +66,7 @@ module.exports = {
// pornpros // pornpros
'milfhumiliation', 'milfhumiliation',
'humiliated', 'humiliated',
'flexiblepositions',
'publicviolations',
'amateurviolations', 'amateurviolations',
'squirtdisgrace',
'cumdisgrace', 'cumdisgrace',
'webcamhackers', 'webcamhackers',
'collegeteens', 'collegeteens',
@@ -79,6 +76,11 @@ module.exports = {
'pornmegaload', 'pornmegaload',
'scorelandtv', 'scorelandtv',
'scoretv', 'scoretv',
// spizoo
'intimatelesbians',
'porngoespro',
'pornstartease',
'thestripperexperience',
// teenscoreclub // teenscoreclub
'maiko', 'maiko',
'ncuksinners', 'ncuksinners',
@@ -93,6 +95,7 @@ module.exports = {
'traxxx', 'traxxx',
// porn doe // porn doe
'forbondage', 'forbondage',
'score',
], ],
}, },
profiles: [ profiles: [
@@ -246,6 +249,7 @@ module.exports = {
'www.tushy.com', 'www.tushy.com',
'www.tushyraw.com', 'www.tushyraw.com',
'www.deeper.com', 'www.deeper.com',
'www.slayed.com',
'sthw-trailer-vixen.ssl-cdn.com', 'sthw-trailer-vixen.ssl-cdn.com',
'sthw-trailer-tushy.ssl-cdn.com', 'sthw-trailer-tushy.ssl-cdn.com',
'sthw-trailer-tushyraw.ssl-cdn.com', 'sthw-trailer-tushyraw.ssl-cdn.com',
@@ -258,6 +262,30 @@ module.exports = {
'streamhw-trailer-blacked.ssl-cdn.com', 'streamhw-trailer-blacked.ssl-cdn.com',
'streamhw-trailer-blackedraw.ssl-cdn.com', 'streamhw-trailer-blackedraw.ssl-cdn.com',
'streamhw-trailer-deeper.ssl-cdn.com', 'streamhw-trailer-deeper.ssl-cdn.com',
'cdn.vixen.com',
'cdn.tushy.com',
'cdn.blacked.com',
'cdn.deeper.com',
'cdn.blackedraw.com',
'cdn.tushyraw.com',
'cdn.slayed.com',
'www.vogov.com',
'www.vogov.com',
'www.nubiles.net',
'www.brattysis.com',
'www.deeplush.com',
'www.detentiongirls.com',
'www.daddyslilangel.com',
'www.myfamilypies.com',
'www.bountyhunterporn.com',
'www.anilos.com',
'www.thatsitcomshow.com',
'www.nubileset.com',
'www.nubilesunscripted.com',
'www.nubilefilms.com',
'www.badteenspunished.com',
'www.cumlouder.com',
'im0.imgcm.com',
], ],
}, },
limits: { limits: {
@@ -270,10 +298,6 @@ module.exports = {
interval: 1000, interval: 1000,
concurrency: 1, concurrency: 1,
}, },
'www.realitykings.com': {
interval: 1000,
concurrency: 1,
},
'westcoastproductions.com': { 'westcoastproductions.com': {
interval: 100, interval: 100,
concurrency: 1, concurrency: 1,
@@ -285,8 +309,15 @@ module.exports = {
}, },
fetchAfter: [1, 'week'], fetchAfter: [1, 'week'],
missingDateLimit: 3, missingDateLimit: 3,
memorySampling: {
enabled: false,
sampleDuration: 300000, // 5 minutes
snapshotIntervals: [],
},
media: { media: {
path: './media', path: './media',
maxSize: 1000,
quality: 80,
thumbnailSize: 320, // width for 16:9 will be exactly 576px thumbnailSize: 320, // width for 16:9 will be exactly 576px
thumbnailQuality: 100, thumbnailQuality: 100,
lazySize: 90, lazySize: 90,

View File

@@ -1,6 +1,6 @@
const config = require('config'); const config = require('config');
exports.up = knex => Promise.resolve() exports.up = (knex) => Promise.resolve()
.then(() => knex.schema.createTable('countries', (table) => { .then(() => knex.schema.createTable('countries', (table) => {
table.text('alpha2', 2) table.text('alpha2', 2)
.unique() .unique()
@@ -792,7 +792,6 @@ exports.up = knex => Promise.resolve()
})) }))
.then(() => knex.schema.createTable('releases_tags', (table) => { .then(() => knex.schema.createTable('releases_tags', (table) => {
table.integer('tag_id', 12) table.integer('tag_id', 12)
.notNullable()
.references('id') .references('id')
.inTable('tags'); .inTable('tags');
@@ -802,6 +801,8 @@ exports.up = knex => Promise.resolve()
.inTable('releases') .inTable('releases')
.onDelete('cascade'); .onDelete('cascade');
table.text('original_tag');
table.unique(['tag_id', 'release_id']); table.unique(['tag_id', 'release_id']);
})) }))
.then(() => knex.schema.createTable('releases_search', (table) => { .then(() => knex.schema.createTable('releases_search', (table) => {
@@ -985,7 +986,6 @@ exports.up = knex => Promise.resolve()
})) }))
.then(() => knex.schema.createTable('chapters_tags', (table) => { .then(() => knex.schema.createTable('chapters_tags', (table) => {
table.integer('tag_id', 12) table.integer('tag_id', 12)
.notNullable()
.references('id') .references('id')
.inTable('tags') .inTable('tags')
.onDelete('cascade'); .onDelete('cascade');
@@ -996,6 +996,8 @@ exports.up = knex => Promise.resolve()
.inTable('chapters') .inTable('chapters')
.onDelete('cascade'); .onDelete('cascade');
table.text('original_tag');
table.unique(['tag_id', 'chapter_id']); table.unique(['tag_id', 'chapter_id']);
})) }))
.then(() => knex.schema.createTable('users_roles', (table) => { .then(() => knex.schema.createTable('users_roles', (table) => {
@@ -1450,6 +1452,7 @@ exports.up = knex => Promise.resolve()
array_to_string(alias, '') ILIKE ('%' || TRIM(search) || '%') OR array_to_string(alias, '') ILIKE ('%' || TRIM(search) || '%') OR
replace(array_to_string(alias, ''), ' ', '') ILIKE ('%' || TRIM(search) || '%') OR replace(array_to_string(alias, ''), ' ', '') ILIKE ('%' || TRIM(search) || '%') OR
url ILIKE ('%' || search || '%') url ILIKE ('%' || search || '%')
ORDER BY similarity(entities.name, search) DESC, name ASC
$$ LANGUAGE SQL STABLE; $$ LANGUAGE SQL STABLE;
CREATE FUNCTION search_actors(query text, min_length smallint DEFAULT 2) RETURNS SETOF actors AS $$ CREATE FUNCTION search_actors(query text, min_length smallint DEFAULT 2) RETURNS SETOF actors AS $$
@@ -1748,6 +1751,7 @@ exports.up = knex => Promise.resolve()
COMMENT ON FUNCTION tags_scenes IS E'@sortable'; COMMENT ON FUNCTION tags_scenes IS E'@sortable';
COMMENT ON FUNCTION search_releases IS E'@sortable'; COMMENT ON FUNCTION search_releases IS E'@sortable';
COMMENT ON FUNCTION search_entities IS E'@sortable';
COMMENT ON FUNCTION search_actors IS E'@sortable'; COMMENT ON FUNCTION search_actors IS E'@sortable';
COMMENT ON FUNCTION search_movies IS E'@sortable'; COMMENT ON FUNCTION search_movies IS E'@sortable';
COMMENT ON FUNCTION search_tags IS E'@sortable'; COMMENT ON FUNCTION search_tags IS E'@sortable';

View File

@@ -0,0 +1,29 @@
exports.up = async (knex) => knex.raw(`
CREATE FUNCTION entities_scenes(entity entities) RETURNS SETOF releases AS $$
WITH RECURSIVE children AS (
SELECT entities.id
FROM entities
WHERE entities.id = entity.id
UNION ALL
SELECT entities.id
FROM entities
INNER JOIN children ON children.id = entities.parent_id
)
SELECT releases FROM releases
INNER JOIN children ON children.id = releases.entity_id
UNION
SELECT releases FROM releases
INNER JOIN children ON children.id = releases.studio_id;
$$ LANGUAGE SQL STABLE;
COMMENT ON FUNCTION entities_scenes IS E'@sortable';
`);
exports.down = async (knex) => knex.raw(`
DROP FUNCTION IF EXISTS entities_scenes;
`);

View File

@@ -0,0 +1,15 @@
exports.up = async (knex) => Promise.resolve()
.then(() => knex.schema.alterTable('releases_tags', (table) => {
table.index('release_id');
}))
.then(() => knex.schema.alterTable('movies_scenes', (table) => {
table.index('scene_id');
}));
exports.down = async (knex) => Promise.resolve()
.then(() => knex.schema.alterTable('releases_tags', (table) => {
table.dropIndex('release_id');
}))
.then(() => knex.schema.alterTable('movies_scenes', (table) => {
table.dropIndex('scene_id');
}));

View File

@@ -0,0 +1,11 @@
exports.up = async (knex) => knex.raw(`
CREATE OR REPLACE FUNCTION entities_scene_total(entity entities) RETURNS integer AS $$
SELECT COUNT(id)
FROM releases
WHERE releases.entity_id = entity.id;
$$ LANGUAGE SQL STABLE;
`);
exports.down = async (knex) => knex.raw(`
DROP FUNCTION IF EXISTS entities_scene_total;
`);

View File

@@ -0,0 +1,8 @@
exports.up = async (knex) => knex.raw(`
CREATE VIEW movies_tagged AS
SELECT * FROM movies;
`);
exports.down = async (knex) => knex.raw(`
DROP VIEW IF EXISTS movies_tagged;
`);

27525
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,13 @@
{ {
"name": "traxxx", "name": "traxxx",
"version": "1.199.3", "version": "1.209.4",
"description": "All the latest porn releases in one place", "description": "All the latest porn releases in one place",
"main": "src/app.js", "main": "src/app.js",
"scripts": { "scripts": {
"start": "node -r source-map-support/register src/init.js", "start": "node -r source-map-support/register src/init.js",
"webpack": "webpack --env=production --mode=production", "webpack": "webpack --env=production --mode=production",
"webpack-dev": "webpack --env=development --mode=development", "webpack-dev": "webpack --env=development --mode=development",
"webpack-watch": "webpack --progress --colors --watch --env=development --mode=development", "webpack-watch": "webpack --progress --color --watch --env=development --mode=development",
"babel": "babel src --source-maps -d dist", "babel": "babel src --source-maps -d dist",
"babel-watch": "babel src -w --source-maps -d dist", "babel-watch": "babel src -w --source-maps -d dist",
"build": "babel src --source-maps -d dist && webpack --env=production --mode=production", "build": "babel src --source-maps -d dist && webpack --env=production --mode=production",
@@ -40,38 +40,37 @@
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.12.10", "@babel/cli": "^7.12.10",
"@babel/core": "^7.8.4", "@babel/core": "^7.8.4",
"@babel/eslint-parser": "^7.16.0",
"@babel/plugin-proposal-optional-chaining": "^7.8.3", "@babel/plugin-proposal-optional-chaining": "^7.8.3",
"@babel/preset-env": "^7.8.4", "@babel/preset-env": "^7.8.4",
"@babel/register": "^7.8.3", "@babel/register": "^7.8.3",
"@vue/compiler-sfc": "^3.0.4", "autoprefixer": "^10.4.0",
"autoprefixer": "^9.7.4",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-preset-airbnb": "^3.3.2", "babel-preset-airbnb": "^5.0.0",
"css-loader": "^5.0.1", "css-loader": "^6.5.0",
"eslint": "^7.20.0", "eslint": "^8.1.0",
"eslint-config-airbnb": "^17.1.1", "eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb-base": "^13.2.0", "eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.20.1", "eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.18.3", "eslint-plugin-react": "^7.18.3",
"eslint-plugin-vue": "^6.2.1", "eslint-plugin-vue": "^8.0.3",
"eslint-watch": "^4.0.2", "eslint-watch": "^7.0.0",
"eslint-webpack-plugin": "^2.5.2", "eslint-webpack-plugin": "^3.1.0",
"mini-css-extract-plugin": "^1.3.3", "mini-css-extract-plugin": "^2.4.3",
"node-sass": "^5.0.0", "node-sass": "^6.0.1",
"postcss-loader": "^3.0.0", "postcss-loader": "^6.2.0",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"sass-loader": "^11.0.1", "sass-loader": "^12.3.0",
"style-loader": "^0.23.1", "style-loader": "^3.3.1",
"vue-loader": "^16.1.2", "vue-loader": "^16.8.2",
"webpack": "^5.11.0", "webpack": "^5.11.0",
"webpack-cli": "^3.3.11" "webpack-cli": "^4.9.1"
}, },
"dependencies": { "dependencies": {
"@casl/ability": "^5.2.2", "@casl/ability": "^5.2.2",
"@graphile-contrib/pg-order-by-related": "^1.0.0-beta.6", "@graphile-contrib/pg-order-by-related": "^1.0.0-beta.6",
"@graphile-contrib/pg-simplify-inflector": "^5.0.0-beta.1", "@graphile-contrib/pg-simplify-inflector": "^6.1.0",
"acorn": "^8.0.4", "acorn": "^8.0.4",
"array-equal": "^1.0.0", "array-equal": "^1.0.0",
"aws-sdk": "^2.847.0", "aws-sdk": "^2.847.0",
@@ -88,62 +87,62 @@
"cloudscraper": "^4.6.0", "cloudscraper": "^4.6.0",
"config": "^3.2.5", "config": "^3.2.5",
"connect-session-knex": "^2.0.0", "connect-session-knex": "^2.0.0",
"convert": "^1.6.2", "convert": "^4.2.4",
"cookie": "^0.4.0", "cookie": "^0.4.0",
"csv-stringify": "^5.3.6", "csv-stringify": "^5.3.6",
"dayjs": "^1.8.21", "dayjs": "^1.8.21",
"dompurify": "^2.0.11", "dompurify": "^2.0.11",
"ejs": "^3.0.1", "ejs": "^3.0.1",
"express": "^4.17.1", "express": "^4.17.1",
"express-promise-router": "^3.0.3", "express-promise-router": "^4.1.0",
"express-react-views": "^0.11.0", "express-react-views": "^0.11.0",
"express-session": "^1.17.1", "express-session": "^1.17.1",
"face-api.js": "^0.22.2", "face-api.js": "^0.22.2",
"faker": "^5.1.0", "faker": "^5.1.0",
"file-type": "^14.1.4", "file-type": "^16.5.3",
"fluent-ffmpeg": "^2.1.2", "fluent-ffmpeg": "^2.1.2",
"fs-extra": "^7.0.1", "fs-extra": "^10.0.0",
"graphile-utils": "^4.5.6", "graphile-utils": "^4.12.2",
"graphql": "^14.6.0", "graphql": "^15.4.0",
"html-entities": "^2.3.2", "html-entities": "^2.3.2",
"iconv-lite": "^0.5.1", "iconv-lite": "^0.6.3",
"inquirer": "^7.3.3", "inquirer": "^8.2.0",
"jsdom": "^16.3.0", "inspector-api": "^1.4.2",
"knex": "^0.21.13", "jsdom": "^18.0.0",
"knex": "^0.95.12",
"knex-migrate": "^1.7.4", "knex-migrate": "^1.7.4",
"longjohn": "^0.2.12", "longjohn": "^0.2.12",
"mime": "^2.4.4", "mime": "^2.4.4",
"mitt": "^2.1.0", "mitt": "^3.0.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"nanoid": "^2.1.11", "nanoid": "^3.1.30",
"node-fetch": "^2.6.7",
"object-merge-advanced": "^12.1.0", "object-merge-advanced": "^12.1.0",
"object.omit": "^3.0.0", "object.omit": "^3.0.0",
"opn": "^5.5.0", "opn": "^6.0.0",
"pg": "^8.5.1", "pg": "^8.5.1",
"postgraphile": "^4.10.0", "postgraphile": "^4.10.0",
"postgraphile-plugin-connection-filter": "^1.1.3", "postgraphile-plugin-connection-filter": "^2.2.2",
"promise-task-queue": "^1.2.0", "promise-task-queue": "^1.2.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^16.13.0", "sharp": "^0.29.2",
"react-dom": "^16.13.0",
"sharp": "^0.27.2",
"showdown": "^1.9.1", "showdown": "^1.9.1",
"source-map-support": "^0.5.16", "source-map-support": "^0.5.16",
"template-format": "^1.2.5", "template-format": "^1.2.5",
"tippy.js": "^6.3.1", "tippy.js": "^6.3.1",
"tough-cookie": "^3.0.1", "tough-cookie": "^4.0.0",
"tty-table": "^2.8.12",
"tunnel": "0.0.6", "tunnel": "0.0.6",
"undici": "^4.13.0",
"url-pattern": "^1.0.3", "url-pattern": "^1.0.3",
"v-tooltip": "^2.0.3", "v-tooltip": "^2.0.3",
"video.js": "^7.11.4", "video.js": "^7.11.4",
"videojs-vr": "^1.7.1", "videojs-vr": "^1.7.1",
"vue": "^3.0.4", "vue": "^3.2.20",
"vue-router": "^4.0.1", "vue-router": "^4.0.12",
"vuex": "^4.0.0-rc.2", "vuex": "^4.0.2",
"why-is-node-running": "^2.2.0", "why-is-node-running": "^2.2.0",
"winston": "^3.2.1", "winston": "^3.2.1",
"winston-daily-rotate-file": "^4.4.2", "winston-daily-rotate-file": "^4.4.2",
"yargs": "^13.3.0" "yargs": "^17.2.1"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1172.7 153" style="enable-background:new 0 0 1172.7 153;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M123.4,36.3l-0.2-1c-1.1-4.4-2.9-8.5-5.4-12.2c-2.5-3.7-5.4-6.9-8.9-9.6s-7.3-4.8-11.6-6.2C93,5.8,88.6,5,84,5
H70.8v132.9c0,2.4,0.6,4.4,2,6.1c1.3,1.7,3.1,2.9,5.3,3.6l4.8,1.5H40.6l4.8-1.5c2.2-0.7,4-1.9,5.3-3.6c1.3-1.7,2-3.8,2-6.1V5H39.3
c-4.6,0-9,0.7-13.3,2.2s-8.1,3.5-11.6,6.2S8.1,19.3,5.6,23c-2.5,3.7-4.3,7.8-5.4,12.2l-0.2,1L6.6,4.2h109.9L123.4,36.3z"/>
<path class="st0" d="M216.9,104.2c3.7,6.8,7,12.6,9.8,17.4s5.6,9,8.3,12.5s5.5,6.5,8.5,8.9c3,2.4,6.5,4.5,10.5,6.1h-24.4
c-5.3,0-9.6-1.5-12.9-4.5s-6.4-7.1-9.1-12.2c-2.7-5.1-5.4-11.1-8.1-17.9s-6-14-9.8-21.4c-2.6-5-5.2-8.3-7.7-9.9
c-2.5-1.7-5.9-2.5-10.1-2.5h-9.1v57.5c0,2.4,0.7,4.4,2.1,6.1c1.4,1.7,3.2,2.9,5.6,3.6l4.8,1.2h-43.7l5.2-1.2
c2.3-0.7,4.2-1.9,5.6-3.6c1.4-1.7,2.1-3.8,2.1-6.1V15.4c0-2.3-0.7-4.4-2.1-6.1c-1.4-1.7-3.2-2.9-5.6-3.6l-5-1.5h48.8
c9.1,0,16.6,1,22.4,3s10.4,4.7,13.7,8.2c3.3,3.5,5.6,7.5,6.8,12.1s1.9,9.6,1.9,14.8c0,4.8-0.5,9.4-1.7,13.8c-1.1,4.4-3,8.3-5.8,11.7
c-2.8,3.5-6.6,6.2-11.6,8.4s-11.3,3.5-18.8,4c2.8,0.4,5.4,1,7.9,1.8c2.5,0.8,4.9,1.9,7.1,3.4c2.3,1.5,4.5,3.6,6.6,6.3
c2.1,2.7,4.4,6.1,6.7,10.3L216.9,104.2z M180.5,79.8c2.8,0,5.7-0.8,8.8-2.5s5.9-4,8.5-7.1c2.5-3.1,4.7-7,6.3-11.6
c1.7-4.6,2.5-10,2.5-16c0-5.9-0.8-11.2-2.5-15.9c-1.7-4.7-3.8-8.6-6.3-11.7s-5.4-5.5-8.5-7.1s-6-2.5-8.8-2.5h-17.6v74.5L180.5,79.8
L180.5,79.8z"/>
<path class="st0" d="M340.9,147.4c1.8-0.5,3.1-1.6,3.9-3.2c0.8-1.6,1-3.2,0.4-4.9L332,99.8h-45.9l-13.3,39.3
c-0.7,1.8-0.6,3.5,0.2,5.1c0.8,1.6,2.1,2.7,3.9,3.2l5.6,1.7h-25l3.5-1c2.8-0.7,5.1-2,7.1-3.9s3.5-4.3,4.5-7L317.1,4.2h1l44.5,133.3
c0.8,2.5,2.2,4.7,4.1,6.5c1.9,1.9,4.2,3.1,6.8,3.8l4.1,1.2h-42.2l5.6-1.7L340.9,147.4L340.9,147.4z M331.4,99l-22.6-67.7L286.3,99
H331.4z"/>
<path class="st0" d="M515.8,4.2L511,5.7c-2.2,0.7-4,1.9-5.3,3.6c-1.3,1.7-2,3.8-2,6.1v133.7H503L398,13.3v124.8c0,2.4,0.6,4.4,2,6.1
c1.3,1.7,3.1,2.9,5.3,3.6l4.8,1.2h-25l4.8-1.2c2.2-0.7,4-1.9,5.3-3.6c1.3-1.7,2-3.8,2-6.1V15.4c0-2.3-0.7-4.4-2-6.1
c-1.3-1.7-3.1-2.9-5.3-3.6L385,4.2h28.8l89,115.3V15.4c0-2.3-0.7-4.4-2-6.1c-1.3-1.7-3.1-2.9-5.3-3.6l-4.8-1.5H515.8z"/>
<path class="st0" d="M576.9,63.6c4.1,2.6,8.6,5.3,13.5,7.9c4.8,2.6,9.3,5.7,13.5,9.2s7.6,7.7,10.3,12.5c2.8,4.8,4.1,10.8,4.1,17.8
c0,5.5-1.5,10.6-4.3,15.3c-2.9,4.7-6.7,8.7-11.4,12.1c-4.7,3.4-9.9,6-15.7,7.9c-5.8,1.9-11.7,2.8-17.6,2.8c-3.5,0-7.1-0.4-11-1.1
s-8.1-2.2-12.6-4.2c-1.7-0.8-3.9-1.4-6.8-1.5s-5.6,0.1-8.1,0.9l-2.7-24.4c0.5,1.9,1.2,3.7,1.9,5.4c0.7,1.5,1.4,3.1,2.2,4.8
s1.7,3.1,2.8,4.4c2.5,2.9,5.2,5.3,8.2,7.2s6,3.5,9.1,4.7c3.1,1.2,6.2,2,9.2,2.5c3,0.5,5.7,0.7,8.1,0.7c3.7,0,7.3-1,10.8-3.1
s6.5-4.8,9.1-8.3c2.6-3.5,4.7-7.4,6.2-11.8c1.5-4.4,2.3-9,2.3-13.7c0-2.8-0.9-5.5-2.8-8.1s-4.2-5.2-7.1-7.7
c-2.9-2.5-6.2-4.9-9.8-7.1c-3.7-2.3-7.3-4.6-11.1-6.9c-4-2.5-8-4.9-12.1-7.4c-4.1-2.4-7.7-5.1-11-8.1s-5.9-6.5-7.9-10.6
c-2-4.1-3-9-3-14.8c0-5.5,1-10.5,3-15c2-4.5,4.8-8.3,8.4-11.5c3.6-3.2,7.9-5.6,12.8-7.4c5-1.7,10.4-2.6,16.3-2.6
c3.6,0,6.9,0.3,9.8,0.8c3,0.5,6.2,1.7,9.8,3.5c1.9,1,4.2,1.7,6.7,2.2c2.5,0.5,5.8,0,9.8-1.5l2.7,25c-1.5-3.3-3.1-6.4-4.8-9.3
c-1.5-2.5-3.3-5-5.3-7.7s-4.2-4.7-6.5-6.2c-5-2.9-9.1-4.6-12.3-5.1s-6.6-0.7-10-0.7c-2.9,0-5.9,0.9-8.9,2.6c-3,1.7-5.8,3.9-8.4,6.6
s-4.6,5.8-6.2,9.2c-1.6,3.5-2.4,6.9-2.4,10.4c0,3.7,0.8,6.9,2.5,9.6s3.9,5.1,6.6,7.2c2.8,2.1,5.9,4.2,9.4,6.2
C569.7,59.3,573.3,61.4,576.9,63.6z"/>
<path class="st0" d="M728.4,36.3l-0.2-1c-1.1-4.4-2.9-8.5-5.4-12.2c-2.5-3.7-5.5-6.9-8.9-9.6s-7.3-4.8-11.6-6.2
C698,5.8,693.6,5,689,5h-19.9v66.6h20.7c2.3,0,4.4-0.6,6.1-2c1.7-1.3,2.9-3.1,3.6-5.3l2.5-8.7v32.7l-2.5-8.7c-0.7-2.2-1.9-4-3.6-5.3
c-1.7-1.3-3.8-2-6.1-2h-20.7v65.4c0,2.4,0.7,4.4,2,6.1c1.3,1.7,3.1,2.9,5.3,3.6l4.8,1.5h-42.2l4.8-1.5c2.2-0.7,4-1.9,5.3-3.6
c1.3-1.7,2-3.8,2-6.1V15.2c0-2.3-0.7-4.4-2-6.1c-1.3-1.7-3.1-2.9-5.3-3.6L638.9,4h82.8L728.4,36.3z"/>
<path class="st0" d="M772.8,144c1.3,1.7,3.1,2.9,5.3,3.6l4.8,1.5h-42.2l4.8-1.5c2.2-0.7,4-1.9,5.3-3.6c1.3-1.7,2-3.8,2-6.1V15.2
c0-2.3-0.7-4.4-2-6.1c-1.3-1.7-3.1-2.9-5.3-3.6L740.6,4h42.2L778,5.4c-2.2,0.7-4,1.9-5.3,3.6c-1.3,1.7-2,3.8-2,6.1v122.7
C770.8,140.3,771.4,142.3,772.8,144z"/>
<path class="st0" d="M920.8,147.6l4.1,1.2h-42.2l6-1.7c1.1-0.3,1.9-1,2.4-2.1c0.5-1.1,0.4-2.2-0.3-3.3l-32.5-56.3L819,141.8
c-0.4,1.1-0.4,2.2,0.1,3.2c0.5,1,1.3,1.7,2.4,2l6.8,1.9h-25l5.2-1.5c4.7-1.2,8.4-3.9,11.2-8.1l38.1-54.9l-42.6-74.1
c-1.9-2.6-4.5-4.4-7.7-5.2L803.3,4h42.2l-6,1.7c-1.1,0.3-1.9,1-2.4,2.1c-0.5,1.1-0.4,2.2,0.3,3.3l32.5,56.3L909.2,11
c0.4-1.1,0.4-2.2-0.1-3.2c-0.5-1-1.3-1.7-2.4-2L899.9,4h25l-5.2,1.5c-4.7,1.2-8.4,3.9-11.2,8.1l-38.1,54.9l42.6,74.1
C915.1,145.1,917.7,146.8,920.8,147.6z"/>
<path class="st0" d="M1042.5,117.8l-9.7,31.3h-90.2l4.8-1.5c2.2-0.7,4-1.9,5.3-3.6c1.3-1.7,2-3.8,2-6.1V15.2c0-2.3-0.7-4.4-2-6.1
c-1.3-1.7-3.1-2.9-5.3-3.6L942.6,4h82.8l6.6,32.1l-0.2-1c-1.1-4.4-2.9-8.5-5.4-12.2c-2.5-3.7-5.4-6.9-8.9-9.6
c-3.4-2.7-7.3-4.8-11.6-6.2c-4.3-1.5-8.7-2.2-13.3-2.2h-19.9v66.6h20.7c2.3,0,4.4-0.6,6.1-2c1.7-1.3,2.9-3.1,3.6-5.3l2.5-8.7v32.7
l-2.5-8.7c-0.7-2.2-1.9-4-3.6-5.3c-1.7-1.3-3.8-2-6.1-2h-20.7v65.4c0,2.4,0.7,4.4,2,6.1c1.3,1.7,3.1,2.9,5.3,3.6l1.7,0.4h21.5
c8.6,0,16.3-2.4,23.2-7.2s11.8-11.2,14.7-19.3L1042.5,117.8z"/>
<path class="st0" d="M1111.3,4c10.8,0,20.1,1.9,27.8,5.7c7.7,3.8,14.1,9,19.1,15.5c5,6.6,8.6,14.3,11,23.1s3.5,18.3,3.5,28.4
c0,10.2-1.2,19.7-3.5,28.5c-2.3,8.8-6,16.4-11,23s-11.3,11.7-19.1,15.4s-17,5.6-27.8,5.6h-56.4l4.8-1.5c2.2-0.7,4-1.9,5.3-3.6
c1.3-1.7,2-3.8,2-6.1V15.2c0-2.3-0.7-4.4-2-6.1c-1.3-1.7-3.1-2.9-5.3-3.6l-4.8-1.5L1111.3,4L1111.3,4z M1111.2,148.3
c7.2,0,13.4-1.9,18.8-5.7c5.4-3.8,9.9-8.9,13.6-15.4c3.7-6.5,6.4-14.1,8.2-22.8c1.8-8.7,2.7-17.9,2.7-27.7c0-9.8-0.9-19-2.7-27.7
c-1.8-8.7-4.5-16.3-8.2-22.8c-3.7-6.5-8.2-11.6-13.6-15.3s-11.7-5.6-18.8-5.6h-26.1v132.9c0,2.4,0.7,4.4,2,6.1
c1.3,1.7,3.1,2.9,5.3,3.6l1.7,0.4L1111.2,148.3L1111.2,148.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

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