diff --git a/flow-typed/homepage.js b/flow-typed/homepage.js index a2bbeb7b7..ee4b1226f 100644 --- a/flow-typed/homepage.js +++ b/flow-typed/homepage.js @@ -4,12 +4,12 @@ declare type HomepageObject = { options: any, route: string, title: string, -} +}; declare type HomepageData = { [string]: HomepageObject, default: any => any, -} +}; declare type RowDataItem = { title: any, @@ -19,6 +19,7 @@ declare type RowDataItem = { extra?: any, options?: { channelIds?: Array<string>, + limitClaimsPerChannel?: number, pageSize: number, }, route?: string, diff --git a/homepages/homepage.js b/homepages/homepage.js index 051db2169..1ad88d82d 100644 --- a/homepages/homepage.js +++ b/homepages/homepage.js @@ -2,17 +2,1240 @@ import * as PAGES from 'constants/pages'; import * as ICONS from 'constants/icons'; import * as CS from 'constants/claim_search'; +import React from 'react'; import { parseURI } from 'lbry-redux'; import moment from 'moment'; import { toCapitalCase } from 'util/string'; import { useIsLargeScreen } from 'effects/use-screensize'; export type RowDataItem = { - title: string, + title: any, link?: string, help?: any, - options?: {}, icon?: string, + extra?: any, + options?: { + channelIds?: Array<string>, + limitClaimsPerChannel?: number, + pageSize: number, + }, + route?: string, + hideForUnauth?: boolean, +}; + +export const PRIMARY_CONTENT_CHANNEL_IDS = [ + '3fec094c5937e9eb4e8f5e71e4ca430e8a993d03', + '6184648aab0431c4c95c649072d1f9ff08b9bb7c', + 'b5d31cde873073718c033076656a27471e392afc', + '7317cdf6f62be93b22295062e191f6ba59a5db26', + '1cdb5d0bdcb484907d0a2fea4efdfe0153838642', + 'b516294f541a18ce00b71a60b2c82ad2f87ff78d', + '91e42cc450075f2c4c245bac7617bf903f16b4ce', + 'b6e207c5f8c58e7c8362cd05a1501bf2f5b694f2', + '25f384bd95e218f6ac37fcaca99ed40f36760d8c', + 'f33657a2fcbab2dc3ce555d5d6728f8758af7bc7', + '294f5c164da5ac9735658b2d58d8fee6745dfc45', + '119a2e8c0b50f78d3861636d37c3b44ba8e689b5', + '7b23cca3f49059f005e812be03931c81272eaac4', + 'fb0efeaa3788d1292bb49a94d77622503fe08129', + '797a528c49b6535560f7fd8222b121b0223287c8', + 'bc490776f367b8afccf0ea7349d657431ba1ded6', + '48c7ea8bc2c4adba09bf21a29689e3b8c2967522', + 'bf7490f905904e79de5c90e472bb9e6f26e634a0', + 'df961194a798cc76306b9290701130c592530fb6', + 'cf0be9078d76951e2e228df68b5b0bbf71313aaa', + 'd746ac8d782f94d12d176c7a591f5bf8365bef3d', + '1f30267438257020f08abf452746a48e53a71ad5', + '4ad942982e43326c7700b1b6443049b3cfd82161', + '1cdb5d0bdcb484907d0a2fea4efdfe0153838642', + '6616707e1109aaa1c11b9f399f914d0cfb4f5303', + '4ee7cfaf1fc50a6df858ed0b99c278d633bccca9', + 'b7d02b4a0036114732c072269adb891dc5e34ca4', + '9c51c1a119137cd17ed5ae09daa80c1cab6ac01d', + '5f2a5c14b971a6f5eed0a67dc7af3a3fe5c0b6a4', + '0e2b5b4cf59e859860000ff123dc12a317ad416b', + '3fe68ad3da93065e35c37b14fbeef88b4b7785ed', + 'fd7ffcbafb74412a8812df4720feaf11fe70fe12', + 'b4c30fe36b79870a79c55e1e909adb5ad23f323f', + '92c0f2f3239f1f61496997bd2cdc197ec51bd423', + '29193e9240a71a735639c66ee954e68414f11236', + '25f384bd95e218f6ac37fcaca99ed40f36760d8c', + '87b13b074936b1f42a7c6758c7c2995f58c602e7', + '8d935c6c30510e1dfc10f803a9646fa8aa128b07', + '8f4fecfc836ea33798ee3e5cef56926fa54e2cf9', + '9a5dfcb1a4b29c3a1598392d039744b9938b5a26', + 'c5724e280283cd985186af9a62494aae377daabd', + 'b39833be3032bbe1005f4f719f379a4621faeb13', + '589276465a23c589801d874f484cc39f307d7ec7', + 'fb364ef587872515f545a5b4b3182b58073f230f', + '6c0bf1fed2705d675da950a94e4af004ec975a06', + 'b924ac36b7499591f7929d9c4903de79b07b1cb9', + '113515e893b8186595595e594ecc410bae50c026', + '72f9815b087b6d346745e3de71a6ce5fe73a8677', + 'b0198a465290f065378f3535666bee0653d6a9bb', + '020ebeb40642bfb4bc3d9f6d28c098afc0a47481', + '5c15e604c4207f52c8cf58fe21e63164c230e257', + '273a2fa759f1a9f56b078633ea2f08fc2406002a', + '930fc43ca7bae20d4706543e97175d1872b0671f', + '0cb2ec46f06ba85520a1c1a56706acf35d5176dd', + '057053dfb657aaa98553e2c544b06e1a2371557e', + '64e091964a611a48424d254a3de2b952d0d6565a', + '50ebba2b06908f93d7963b1c6826cc0fd6104477', + '374ff82251a384601da73f30485c3ac8d7f4176b', + '1487afc813124abbeb0629d2172be0f01ccec3bf', + '6a4fa1a68b92336e64006a4310cb160b07854329', + '15f986a262fc6eff5774050c94d174c0533d505d', + '6184648aab0431c4c95c649072d1f9ff08b9bb7c', + '1efa9b640ad980b2ec53834d60e9cff9554979cd', + '064d4999ea15e433e06f16f391922390acab01cb', + '4884e30b93b3c4c123a83154516196095f9e831e', + '2827bfc459c12d7c6d280cbacee750811291d4ba', + '9626816275585ac3443e7cddd1272c8652c23f1d', + 'a2e1bb1fed32c6a6290b679785dd31ca5c59cb5f', + 'd9535951222dd7a1ff7f763872cb0df44f7962bf', + '243b6f18093ff97c861d0568c7d3379606201a4b', + '1ce5ac7bab7f2e82af02305ced3c095e320b52e5', + '3e63119a8503a6f666b0a736c8fdeb9e79d11eb4', + 'e33372c0d8b2cdd3e12252962ee1671d66143075', + '7364ba2ac9090e468855ce9074bb50c306196f4c', + 'd6350f9158825662b99e4b5e0442bcc94d39bc11', + '2a294ea41312c6da8de5ebd0f18dbfb2963bb1a4', + '44c49bbab8a3e9999f3ba9dee0186288b1d960a7', + '2305db36455aa0d18571015b9e9bd0950262aa0f', + '82f1d8c257d3e76b711a5cecd1e49bd3fa6a9de9', + 'faed2b028a9b5a712d5180eaa6fd2aa619f941bc', + '39ac239b5687f7d1c2ba74cd020b3547545dfdaf', + '5737eb22f6119f27c9afccfe73ba710afd885371', + '5f22b6daf7204d73cf79d3ff0b46fc4fe237c7f7', + '3583f5a570af6870504eea5a5f7afad6e1508508', + 'b0e489f986c345aef23c4a48d91cbcf5a6fdb9ac', + 'ba79c80788a9e1751e49ad401f5692d86f73a2db', + 'c54323436f50c633c870298bb374ac8e7560e6cd', + '83725c7ee23bd4a8ca28a4fab0e313409def1dc7', + '61c4e8636704f2f38bbe88b1f30ef0d74d6c0f49', + '87ef9ba36019f7f3bf217cf47511645893b13f2e', + '1bd0adfcf1c75bafc1ba3fc9b65a1a0470df6a91', + '1be15348c51955179b7bf9aa90230a9425927ef6', + '1f45ab3495df2c3be7d9c882bca9966305115cbb', + '7317777e3751efa66218f6da5ef0d01dda69af48', + '3346a4ff80b70ee7eea8a79fc79f19c43bb4464a', + '452916a904030d2ce4ea2440fad2d0774e7296d9', + '2675ef3adf52ebf8a44ff5da4306c293dfa6f901', + 'e2a76643735f8611a561794509c6bb2aac70eb04', + 'dc577db3caf5ff83a3b573ba92f2d447f067eee1', + '89c4cf244099918b1d3ed413df27d4216e97b499', + '4b2b5822c8af3074c6ef9b789a8142d0ef623402', + '3c5794f775975669745c412b0c30f48991d9e455', + '1df464dbb302ced815c61431a5548a273e6de8e1', + '1c0129135a23ff8096d533e0241921859f065f35', + '6d2dac42692c279aed436f000c053c34c3ccec29', + '403cd55421118093e83d490cf7991ebb477a320c', + 'b48a89b235fa577fab38ef56b57008c2aa0655fd', + '06f6e7b9a05f12823c7d93dc04826636ae99c938', + '3772507e49303f6db071f6361494deaafcbbf4cb', + 'e5872eb7237883e4158cf88e96a465f7a674c968', + 'b4ccefa53e0bb5730b56facb9b2ae5ad92c99935', + 'a30c5c8cb8faf78b7ad82118e8fd7039901a5a32', + '5701b00a32d91035baa53e6a65800f0f5d4e520c', + '6f061a2d8cf613a1ccca86468cf38143d2887c18', + '4de30a6590a288684ab200409988c47c17a12ef2', + 'd0dec51ee295fae711466a6642749217b6e48032', + '693d8aa643c30d4afb1a5e712ec57ac4ae699b26', + 'c73409178a35717a9a735aea942945fca53604fc', + 'f58e50a4c5fd2db81e1b5f4f5c36642d45f805c4', + '24fbe1f81dddd872270648f038cf368b49cc4c4a', + '074973ec6f89e0445903c844d02f9b15a64b2222', + 'f40f4a4546dabc9c47d9c75d0e5c0a9ba8581bec', + 'f74655b4911e09c77d2fa0e700d5a76d2bc68ba5', + '16fb96ca5b1713a4cc787e9e2542da724a45c854', + 'c1296488bc1aa7a8c8890509fd231267b3cf9e16', + '0b7925083d4c382cb441f5f44ad626f7627bc198', + 'af0f5d9e055d07c8308da7f6726562420ff0bb82', + 'd6d17103b4aadd46c47236431eb7a96427ef98d7', + '638f9e7b024efc24a14c161f8ccf4bacbcfda10b', + '01c80abaf2f957cd0e37e0a0c58d357070c2b6ff', + '44492321a13a0087c12394d4fb48c208ca6d4b27', + 'cc8f04f02b15a4de03381f1ef506bd270c7b0936', + '3264777dacecd86cb6b5b2f67b7e52b7b3b9f06a', + '1698fe7e7cc0e748d99408e67df73f584e18113f', + '38a83de67a246c72cd793104073968d7440e3509', + '4c4c9e44dd32e618ce56c7ca2e2e2b53e8027779', + '77912e1d53cec04f2343a754dd3ccb1853c5ea66', + '617886394bee35c359766fb4d9ae889b8fd39079', + '5c1777eed58b6729c4502c12b4e2d5f0a78450d5', + '88f9585ed0139d8775c47d2502b60ff028acc17e', + '37f3125b8ae2a19082300e05951d6c33d65b84d3', + '1dd1f89c9fec0450b8f446d88c8ca7eae806c54e', +]; + +export const PRIMARY_CONTENT = { + route: '/$/general', + icon: ICONS.HOME, + title: __('General'), + options: { + claimType: ['stream'], + orderBy: ['release_time'], + pageSize: 20, // temporary, to facilitate screenshots until repitition parameter is added + channelIds: PRIMARY_CONTENT_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const PRIMARY_CONTENT_2 = { + title: __("Don't Be Evil"), + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${ + CS.CHANNEL_IDS_KEY + }=${PRIMARY_CONTENT_CHANNEL_IDS.join(',')}`, + options: { + claimType: ['stream'], + orderBy: ['release_time'], + pageSize: 8, + channelIds: PRIMARY_CONTENT_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const RABBIT_HOLE_CHANNEL_IDS = [ + 'a5af5f42b57d31b982fd700f65b02ee589751b96', + 'ea86138fdfac9891a2e15cec9b2143ef64805435', + 'b541d03b30c3fea017280d8ae1758a9f2035f44f', + '81c637fdba001ff4406123c1fd4f5a1c6e1772f7', + '0c4a8b59b2e1bf396210be96f690d8d37251d39b', + 'a190ec65b6d67df868be2208c62510c257ace16e', + 'df75764e06247ccec50dbc87a9c4a8a95a32658d', + 'd70c3d47eff085d56e6328fc2f2def163b1d21fb', + '02f3c6b00fcaa365c5858352ca1ee149aea7b90f', + '6259aac793195c93a4dce1940e2581c238fd2021', + '526b15b49e5ff7d1fd9443b7f9b30ad1194c3235', + '70d122698cc6d3511036c7fb2e6dca5c358463de', + 'f14e64d962c226630702f9a61f48ab4f55ecffb9', + 'bc490776f367b8afccf0ea7349d657431ba1ded6', + '935e7ed2c8b2a184ba2f39167f0201a74910235b', + '3fec094c5937e9eb4e8f5e71e4ca430e8a993d03', + '780abbacb30bffd0554a3d6e79764cdc3551a0a5', + 'e8db076af81d517098c81b30c71ce42cf05daeda', + '4407261b86abf43b85448657d9d2a4f13a968d87', + '191a3374da974a9528cd39497ffb31011988dfce', + '40592b2f8bba7f702c62b8ab91402bd1a257ab18', + '0e42d95f05f3543937390f1a573d6fd9840eaa46', + '7a3c90e0e7d7214f6bbe2994a4a5fff6d4afd515', + '8dc55cd4acb6e8d903a85e3bd9b15478bbdad3b5', + 'a8d874a26b64b7cf2584268ffcfe4c5e07aac6d4', + 'f6190681f20cbb905f5ff7d58e568603f81de8ba', + '82f1d8c257d3e76b711a5cecd1e49bd3fa6a9de9', + '302e6aeb7e8f31e17660bbbe5c94ad4e072ba904', + '4651d91cc32c01243069af1f39468928102750dc', + '5e0ee088f3b80915a24dc3b59adf164460141359', + '28945e47d977bb49f8eb2ca4e98ef2ee243e1f2e', + 'e8b0d5e34558b8a852374fd40af1c0150a65504b', + '9170327aa5ad2c6bea0b167f840032036eaf9064', + 'b4fea5d9a31024fd5b6609c188b55bfa883a8ae0', + '3645cf2f5d0bdac0523f945be1c3ff60758f7845', + '0f8078f7710ce929ac176e3df0e08cf0b6ab2125', + 'b325961c50c986f2022313220e5b98da9b0004bc', + '6175f135650778103c72ae3bee8561b75f264586', + '7f1137707c918dab287ac91c9dbb28748696a36b', + 'a527400d6bf96de2bd1811e978f23790748b06e1', + 'eca0cce47d1111668f2ad040ed13fa4924d4c346', + 'e99c0ecc262375abfc2b9548d9bd0c0d11bb3a71', + '5c15e604c4207f52c8cf58fe21e63164c230e257', + '09d4223819ac29d5462a3eea2b1f35b5482770a2', + 'b0198a465290f065378f3535666bee0653d6a9bb', + 'f4c726ebb9e9e6308cae9970c5f1cf430b33ddc1', + '9f58aaa07638c45e6d7be611b5e8714f7cdd09bf', + 'f2318083d4a21c9b1b619ed4d2f420c9766683f5', + '0b3d9716a33b3958bc89fd23d550f17cab5bbf98', + '13edd7e7e2fbaf845699cf2f8f0b1c095bacb05f', + '5663072977d3a0f161780cfd6ddc7507f157ffcd', + '207d310712f28c7e7c3436bb3d86f2481a8cfaf1', + 'b9288432bd089c6f332145aab08a56eec155f307', + '9db218b153feebb1fcc847ee0e5e921c85fc8852', + '56f784fd6682f2b75a64be95f9443eadf2ef4a66', + '2379d6ca19ce29e64035682ed2b94cb6ec18bb83', + '94fb122085a5f934292bee5547085e4961f847e1', + 'e39dd89fc7ace77e84aebc0b4c88182e21196ff4', + 'a4361b1435691b54b6e1abe2546080809c4029f9', + 'ea5810ca7e60b4e906b021eaf3c55c61d2aea6f6', + 'e7ac2c49710f5657760bcb34abf65802f8c8e13c', + '51d000168749e39034f90c90be803f0536ab0243', + '34ecf8b9cd2f49580a49a175589207625ad2ac8d', + 'd388ed630deef5adddd63767e7dd9b0a2fefdf4a', + '2a3ef5da49872fa4c8cc4103c237e8f9fd7634e3', + '4a966b4b5144027d9339922cfc6a03fc66c9f3fb', + 'e0941d15ea9fd1872c58f51b2d2109fc66b4c96e', + 'b04bd5e53b5d72e912d68e09d7f326f5c14fce28', + '818c4e6b66467cea971c9a26d79723c58582af3e', + 'b7a15c35aa63c02b62f3fd8b02a3fe5ae7263ad6', + '07bfd6eb2935e9be50bdec56d34d9227c511f8c6', + 'c7e6f045bbcf10f651d8948605a42758ebda18e7', + 'b89ed227c49e726fcccf913bdc9dec4c8fec99c2', + 'cde3b125543e3e930ac2647df957a836e3da3816', + '88745fbeb9655201b1824ee1cda5c6e718bcb4fd', + '0d2ad3f6c9810bad6c3e7bb0d06caf3c8112a44f', + '68eb3f3e884400f60080bb910055bc11fecd26d2', + 'e11e2fc3056137948d2cc83fb5ca2ce9b57025ec', + 'cec54cfc1b67da757bcab8a8643328717bbd339d', + 'ee1aaf96d05ddf21e96deb681d5ed2f5dea1d237', + '5cad54ea797c4ec339cc3437a12b144a97d63c08', + '8efc01ef6c24793d0f2f0a415b201d22a427a1d9', + 'c34bc395a4ca536acf394d522cee2a240d49dd98', + '9e263a378138a370c89e9554a7315b8aafc40276', + '14541b47e10941a338e38889ae8f679a0db03698', + '6fcbab41969557ece4660326a5f9cacbff747ad8', + 'd10f0ee5ad036d2cfe7f1d898dea0e58dd5a09a6', + 'c145a475a806c7ccce0a81d22e81a88af6ff5c42', + '2677aa4bb592d97c4be07b80124507db18a529f4', + '964c0e89e04bd31a3d876537f9aeef83d47ebb91', + '4d7725281395247e16133f25044cc16d6f0573ec', + '211cd5ccf2e6911928f9009099a9f81986912b28', + '703b5a1045dddd0d8eacbe21ec4fe83093302cc8', + 'a748ca0dc776ec6ea70cfbb928dca17f1054f714', + '02ebbc46574b6a4e7d7aa523b81f847ea7aa368d', + '6d1173b12c14d756ffd268a401431cd2cd2401c3', + '72c796c2fd82f34914bca296a0f5a69151ac0e37', + 'd3b01081547ef997d07fa41cbb377623b1a27e47', + 'cc7f56eafbf2e763e96ace32a8f617fc5672cd75', + 'd3775ea92591d328ca949ac1a9905c4d125a9aaa', + '0755b84db5b73ce79ea1f48dc8fad273725e9667', + '2f04823d34317bb4f4c9624440667ea614942237', + '0a8021998531fb7acf0022653e5660211bf09f9a', + '5499c784a960d96497151f5e0e8434b84ea5da24', + '5097b175c4c58c431424ce3b60901de6ae650127', + '49f1876b382a69414a330995908e326c7b96c132', + '97f9e09764c0cd76b6a1b8567c5a261b49a41dae', + 'e80e3070d5c82d934f09d439fb9ca9eca5e155b8', + 'a757e39ff8abb2e2f13e88c9b7ad0105ea459ed9', + '2556ed1cab9d17f2a9392030a9ad7f5d138f11bd', + 'f67929e214b9d2e6a317f96750093d00c757515a', + 'e5335287649b30009ed07f65cfc99f777af57784', + 'cb80a9d182a3233d55eb32210778b277cf28da13', + '0cefa1d479bd45c7f8cb224e097e63b5307c3f88', + '0f5d9ae65d82b15c58cc8c962ffd11a0fffed646', + 'b36f5f628e63c2c8a0d063c2be08c1f004984d68', + '6b854ef31764b6472242cdfdd2d7f7009aeeca89', + '5774289bd81edf5442aa23693007e611d9be14e4', + '85fc3229d358fc21ccb1648a94a20993cda74182', + '2bef7359b6036a4d83d83ca47a42d18b458ef498', + 'e063b0a1c3c738fec204b2eacc5c97953e7635cf', + '084a9ad04c084a1d30573593a5f6c75d059d6737', + 'b8e52d9cfdfe2fc2c3e05f812ec542c9eca85729', + '7a5b927c47b5c98e439836792272db86201c9302', + '02f3c6b00fcaa365c5858352ca1ee149aea7b90f', + 'f96048ed8ad4e001fb5401f9cb9bae68714e03eb', + 'b356b4300d0b3048997b19c55612e97c12f1f4a0', + '1e0cd736f5bdc43edd57d1ecd205f6b0039c5020', + 'c718a85496d48288cdefab1f73014875c3e3f29e', + '3479ced09893440157be4bb3ca8fc4d56af991c2', + 'd504cf542d5e93af2812426aec690fcc111b6d83', + '999fd8985272943a1e3750cdde1df95aae85f22d', + 'a5d459452ef00c6127fcae56bcb1cfa93af23a00', + 'd8f706316391002c214de187f67b4ed825d5b12b', + '51e1e35410e8749c0720b3e5fd64e5f852709f1c', + 'f0958d20e77d932c26ccfedfcc9319a59b239267', + 'f0ab91c7ce2964d3286803916c6e0630ffa9c8c0', + 'b88d5fc723c5e26cb48f7aaa2b59963864a635e4', + 'ebfdcacd3258e86c936e6d783f9dd166cecdc892', + '745ad866e987dfe2ebf5a8601cd41c2db42c4be5', + '39a1e426f1ed3f83171ae814ca57c8c2f2559b8f', + 'dd96ce703e6b46ed3b6ac1e1309289a345ce92c2', + '64263461dc7c78dbb9c920e393991afa725817a9', + '62c47bb894a31775cb02f68a10cd757338b5f4e8', + 'e80b78ab8133ffc53fbf1dc429e57c3fb9cd9470', + '7fcb028ee0035bbe6d1618653ff9e5ee48d3df50', + 'b0cc819802b92d5701b041934cf0d0d888f21b5d', + '2ea3b0ffb219917a5b6f48847edcf9979db576a6', + '5e10dfdfe8b0dc4b60570e7e27f399ac521fa9e6', + 'f12ae07aa8caa27259795b0b7de382a00067159e', + '58afb8092ec1b72503a252745852fd469b8e0841', + '05fe959c2e0fe1a04e3a4ae2b716e409a9280e9c', + '9e099e2e0920aa8425664affe3fa01aaada61bc1', + 'd881ba593dfa6c6c0bb56f1c848d980711ad3363', + '223edd5d0432c26dba21f821cc261126e8447ae6', + 'a03be4e3463eadd9e3eefa71e7964e485279ad35', + '468ad74f611803b9eb11355d4ddc2f7a2948d93f', + '92b7f813e4210a06fc55968dbea36e5f1f095e6d', + 'd2e58ac96e77babdd34e45b5cda39c75ac9be1fa', + '5dd2355cfabcbc685a8b6e60160213b43dd730d8', + 'e208836ed9fbdbb1bfc70c4e5aa251a0baa25fb0', + '334c5ae331a5602d0f5c2961240261f1f8625846', + '733f6720ab1db4326b3801686313085e8e7b3faa', + 'b164413f24ff6ff3cd46f205820370d8e8775545', + '001e3bcead62e29acaac6b18d947db5d10f5d15e', + 'be822b2a6c9ddaa9df4bc5bec481d7247db403b1', + '735c841ec371efe8d0d6c5cea937ecfb55f918d3', + 'c3a3c6e917bc78cd201b30c4937ef886023cdd97', + '5ea30bcdaddd1177e2588811b14b82c549ff49b9', + '5af17e406f247c5a50f259828ce6c98b3902e64c', +]; + +export const RABBIT_HOLE = { + title: __('The Rabbit Hole'), + route: '/$/rabbithole', + icon: ICONS.RABBIT_HOLE, + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${RABBIT_HOLE_CHANNEL_IDS.join( + ',' + )}`, + options: { + orderBy: ['release_time'], + pageSize: 8, + channelIds: RABBIT_HOLE_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const ENLIGHTENMENT_CHANNEL_IDS = [ + '82f1d8c257d3e76b711a5cecd1e49bd3fa6a9de9', + '3fec094c5937e9eb4e8f5e71e4ca430e8a993d03', + '0871b29c7db6f1ec013694c8146f772539fcffa3', + '537305bc1bd71e2a5d76efacd607fd0f4d95da0c', + 'bf7490f905904e79de5c90e472bb9e6f26e634a0', + 'c07ce3862335cfe9ba72054347c4ea7808ce4eaa', + '0e1aff187fbd3d2b2b16e5e8c213d3e782dafa98', + 'a1303dc6a592605b08d60cac19ecbc1c877d7de7', + '2a294ea41312c6da8de5ebd0f18dbfb2963bb1a4', + 'd6350f9158825662b99e4b5e0442bcc94d39bc11', + '3e7bb536a1b755b6eb64043ae3fa933d5935eaad', + '0518c93a80efeaf06fb4ac4d3fa72cc6390ac100', + 'b8a2d928a3d3f44457a10abd0539b84e4a29c286', + '564789ffe2420980dcf9e00c4746feb5bc0daad0', + '7364ba2ac9090e468855ce9074bb50c306196f4c', + 'e33372c0d8b2cdd3e12252962ee1671d66143075', + '3e63119a8503a6f666b0a736c8fdeb9e79d11eb4', + '1ce5ac7bab7f2e82af02305ced3c095e320b52e5', + '588ff6ffc72884e61e8d19a9412d6db9ec67167e', + 'b51872361cc68c914eb7c6f2d22eace9570a9f4a', + '51d34684ec97cc7057f2c371d8edbadb6b841707', + '7d30976c407fa3cf82675f7d1e8ea99b5ab2959d', + '64adb5d029acaff293b2934e870d3976760a1353', + 'd9c552d38238f00503741e8e468cd3da612b42c4', + '0831bef6095a57ec440f626aac2a650a20282945', + '81c637fdba001ff4406123c1fd4f5a1c6e1772f7', + 'ddc7f2030c474ca4c9c0043bf19ec0bf79e2783f', + '2827bfc459c12d7c6d280cbacee750811291d4ba', + '0b875d01f2578bde0cbb221eb6a67f23f2222823', + '47e1d179bd2753e6e53f28f5e99fb090d336d2e8', + '5c4370bfff3070458df198f6ba60c6eb1244c014', + '6184648aab0431c4c95c649072d1f9ff08b9bb7c', + '45e55a50627305311479123e0fec171e16a0cd0f', + 'c62490d59850450bc8acf26e227f56aee4e9bdf5', + '07e4546674268fc0222b2ca22d31d0549dc217ee', + '1487afc813124abbeb0629d2172be0f01ccec3bf', + '8e9ef4a69ef17507d1a3649573999a61e97f262c', + 'e918922b39e09492e0c54828ee58e0cd7165e950', + '64e091964a611a48424d254a3de2b952d0d6565a', + 'ffc92d8fddf384075f871445d67090887497c587', + '057053dfb657aaa98553e2c544b06e1a2371557e', + '0cb2ec46f06ba85520a1c1a56706acf35d5176dd', + 'd421f5954690807d3e5749e9a9671d7b067ef9e5', + '711da3ea1683900643021c58342b1608e9be0524', + 'a77b073817c8b25edcea146feb84c726efba8269', + '526b15b49e5ff7d1fd9443b7f9b30ad1194c3235', + '5c15e604c4207f52c8cf58fe21e63164c230e257', + 'b0198a465290f065378f3535666bee0653d6a9bb', + '2eefe1b1cfdcf6c58a0fe37f71dffca36a41030a', + '6c0bf1fed2705d675da950a94e4af004ec975a06', + 'c5724e280283cd985186af9a62494aae377daabd', + '5b8c91cdf40b2b0c14a2ef1a4fbe987a34d4677c', + 'd25ae97a1516f5700fc717152b885f33da47f12b', + '56f784fd6682f2b75a64be95f9443eadf2ef4a66', + 'f07a506ee0396b004a7b535f3207a69387fb5a86', + '2c9485e000eac29349bc4538a91d5a45ec56b126', + 'b4c30fe36b79870a79c55e1e909adb5ad23f323f', + 'da5534547c15856646c1bd281313ddd55cbec407', + '495a668d18b93c11079f1ce93195a330fe35e603', + '2677aa4bb592d97c4be07b80124507db18a529f4', + '74e380497449d9eb13de9bc4038676097e4730fe', + '36e6a8937381df34825dfbc8a85f38c30de02eee', + 'ce59b0c52f73407a8bcf95c604803dd8c9c30986', + '92fc977af0e937e9ed6b135a54ae01f978d9cb04', + 'e39dd89fc7ace77e84aebc0b4c88182e21196ff4', + '6ab0d775b951fa2ba3770bb72e129663d963f08a', + '2425da1f0245d08e53559b2f4243f82a2a459505', + '7a8954b2c09cb835f4b90be69fd4a5fc4f1b5f04', + '1cdb5d0bdcb484907d0a2fea4efdfe0153838642', + '68846c9a38ffac12c9b59a2f989a6554a1fada3c', + '0cd2ffa6045eafce28c1abcb518688bed8c79acf', + 'ae64f8ff59f5c226b61434eee805afea56b85a97', + '5c3ae8555f9706bff568d28549b8d66ed05fd490', + '0ec0442f7faf0b3aa18fcef68dccadc04c3e7bd6', + 'd388ed630deef5adddd63767e7dd9b0a2fefdf4a', + '76a00fbe5bec7fe7f7649d4c74c6ede151f083ee', + '4a966b4b5144027d9339922cfc6a03fc66c9f3fb', + '120d6665e352eb1733396a59bd3ffea87268033a', + '5190f00b950ae96607a5f1f1585b06dc1d869ef4', + '1f30267438257020f08abf452746a48e53a71ad5', + '5640bb7d84d8953d367841909967ab345f2c11ca', + 'ddc7f2030c474ca4c9c0043bf19ec0bf79e2783f', + 'f14e64d962c226630702f9a61f48ab4f55ecffb9', + 'cec54cfc1b67da757bcab8a8643328717bbd339d', + '46be492ee0f56db11e005991c537c867a8682f77', + 'a403ce7eff82b75a530dffd211ddc69847be4425', + '8c3b45178de9a3636753271b034061c7e4b8c3ea', + 'f37bc3cbe8aaf2826cc6e42f2cd9b41cb68be191', + 'cab85829af32668a3f78f3fe9c18dfcd6793b56d', + 'a0976c3d6e0948c55c935006a1f87799fc03f413', + '39ac239b5687f7d1c2ba74cd020b3547545dfdaf', + '22076b79263e9c2696ca3198843d85c2066ee30d', + '6563ad2e10baf2c4f3624dab2b129999222f3fa7', + '4262bceff4420f24349944b3d9a02fd331ca9f34', + '87515affb1d52602a0a456b400482d7db9cf7de4', + 'a68e2f8fcf4a2e201bdc700fedcfcd0eb429bb7f', + '06b6d6d6a893fb589ec2ded948f5122856921ed5', + '5a1b164d0a2e7adf1db08d7363ea1cb06c30cd74', + '703b5a1045dddd0d8eacbe21ec4fe83093302cc8', + '4f274af7dfbcfc15803d32eef9bd36a441aa6de2', + 'ae12172e991e675ed842a0a4412245d8ee1eb398', + 'e04ece044748d52b0fddde21b5b1a2bd3b4b8b43', + '177946d040a1e1cb0c608d115c2419e49ffb8ba7', + 'd16e18834d123c5df038358e4964b9a1b5c8b464', + '6280fe7926ba4421c8f9bc0006407766d587bd53', + '0755b84db5b73ce79ea1f48dc8fad273725e9667', + '4ecc029cac207edb5bb7770947ebb9e84f7ebab9', + 'dfa7d9854c7935b9312ed0aac66aa3dd3f48684e', + '1d729d8a4bbed9f3e9bec0cf1e958980569b0681', + 'a6bb6b4d8ab63b6580855903da440789aec2d5fb', + 'c191c83abf8b5c892ba2e96e629414a0d5acc9fb', + '9b533cddf16a00f9c1fef598db1b71b8dfa6f9b8', + '4b2b5822c8af3074c6ef9b789a8142d0ef623402', + 'dc577db3caf5ff83a3b573ba92f2d447f067eee1', + 'a034887d7bc1baf3d8503fa1d940ba4b753130a6', + '14238e19a38d7bf1d748a0d8eb2a90c46de01f9c', + '992dec920b87ed9ce06dc7ae69df7c8be03afb85', + '6ea7e01f0dbdea4efc857a5cdb1f03770ff570c4', + 'f85c9989f66e09b8d248e65f838e0d2cd7126cb9', + 'a3e777832e63ab29cf36010c58004aef955dc5b5', + '8ddde2e2330194594e1b70d90b2170843a84e786', + '0657cacd7dd60fd25032b998b98ef5822700667a', + '06f6e7b9a05f12823c7d93dc04826636ae99c938', + '941ea9f49e136a45e3c1ebded90aef66dccaa07a', + 'ca60ebc129f11ced61e010d2a0a27656cb2003f7', + '116d17f196e19681d00d19803d2674cd740391dc', + 'f66c7b4fa8d6c62cf420e100a28b144d78cda1d2', + 'e329ce51a201d565f6b87c6c260df51396e18a40', + '5701b00a32d91035baa53e6a65800f0f5d4e520c', + '3479ced09893440157be4bb3ca8fc4d56af991c2', + '8a42cda79b4ccc9bcf06a5cf286a18fe0ae6029b', + '0fd0cfcd533255ea682f3488a5778075d7e29bbb', + '96f98fe1a19b86eda83b3c29f6cdabd1e2379943', + '47c979a88e6afe85395b8205e30a57f90365947c', + '4fd6950858377dc247952b6c94065273c8fd083e', + '4de30a6590a288684ab200409988c47c17a12ef2', + 'd74267e5bf95d71e1cd0c16f7e77f849dff5edd7', + 'dd96ce703e6b46ed3b6ac1e1309289a345ce92c2', + '62c47bb894a31775cb02f68a10cd757338b5f4e8', + 'f58e50a4c5fd2db81e1b5f4f5c36642d45f805c4', + 'e2b63a6a359896b5f7fdfac500a321a4bfd2871a', + 'cb7a6655353e39198d01172f47b4349e798cb95e', + '2f5c671e5e1f9dc5714b51b938d818cee6421a2b', + 'f74655b4911e09c77d2fa0e700d5a76d2bc68ba5', + '16fb96ca5b1713a4cc787e9e2542da724a45c854', + 'c1296488bc1aa7a8c8890509fd231267b3cf9e16', + 'f9e35814abee0aeab5d85c06b99bc00a8e1d3d1b', + '0b7925083d4c382cb441f5f44ad626f7627bc198', + '468ad74f611803b9eb11355d4ddc2f7a2948d93f', + '01c80abaf2f957cd0e37e0a0c58d357070c2b6ff', + '7cefac5dfb1013fe53a1c9717770535f1d622c90', + '733f6720ab1db4326b3801686313085e8e7b3faa', + '3264777dacecd86cb6b5b2f67b7e52b7b3b9f06a', + '6c5e16c3faf9dfc7edc1fdfa82d3d16a7af55a34', + '5c1777eed58b6729c4502c12b4e2d5f0a78450d5', + '88f9585ed0139d8775c47d2502b60ff028acc17e', + '37f3125b8ae2a19082300e05951d6c33d65b84d3', + '1dd1f89c9fec0450b8f446d88c8ca7eae806c54e', +]; + +export const ENLIGHTENMENT = { + title: __('Enlightenment'), + route: '/$/enlightenment', + icon: ICONS.ENLIGHTENMENT, + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${ + CS.CHANNEL_IDS_KEY + }=${ENLIGHTENMENT_CHANNEL_IDS.join(',')}`, + options: { + orderBy: ['release_time'], + pageSize: 12, + channelIds: ENLIGHTENMENT_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const GAMING_CHANNEL_IDS = [ + 'b7d204c8ac9b0b5df4ffc4350afa432bf579543e', + '02c020b2fab7dd1fbd175c3b22947688c0a219e5', + 'e8c71ade66ffb2cd7be3fa08f1d0a19ac70bfc65', + '15c88c561f7e4c4cdd6fb4e32c35e593db09a8a4', + '1d729d8a4bbed9f3e9bec0cf1e958980569b0681', + '514df20b9d2cce22725d5305a8ba019547188736', + '199eba05b6ecccab919e26a0cb7dacd544f25700', + 'ff9dddaef1f0c7938d7a4a170abef24c70e4cec7', + '164845c52a9407f3406494f87523f2956c2b7936', + '3a3af9d672ad2166737758f4e35ac6fd6f1235f9', + 'ee09d6c4ac3fbfc99635875d18f2aa98037d2602', + 'd746ac8d782f94d12d176c7a591f5bf8365bef3d', + '520de75a0373643c14168536940e596ff8ece24c', + 'e715c457b4a3e51214b62f49f05303bba4ee5be9', + '1d31472f4ed71162268afb92a5bf9d60b130317d', + '9218bf25ba0d146a320ef3be7ebb85069cbe3353', + 'de503eb9fe4e68aa556abf94649dcd87ef42c985', + '9071c16e86e86cb94e5364b580522b3aca55cb4d', + '8d0770159e22943c37962b4d203fb85bf3057b3f', + '9456c69274d4d608971d4d92f6218185d0831b11', + 'a91d3667c0c1f5344d6b41115506c888ca0b90c9', + '9ccea33130f6e22bf0dec9448e0ecbbfa987ee42', + 'db35d0216ac55ef46420b5228263bb04655599a4', + '36a291fa2c43bc42b8b589d3fb7e7a121868870d', + '20b4b5ac6ddf68767e0da6765bcb0b389425d252', + 'd700ab31f4027a274b87288930c7a7d7fe0eae95', + '489b75de1aeb6fe94e3dd930a231b7587b66d08f', + '046f085572c0cd72127a3ae7e26b1f9881247840', + '90f94b559aa94d5354326a6c0516c8f681930b57', + '8f7cebbc8213cbf0a4cc5b80da080c1b42375983', + 'fce4a5526d6d541d9f971e5cd15d98376b6ff607', + 'd6350f9158825662b99e4b5e0442bcc94d39bc11', + 'e233d2b45b8287acabf43702f6d9b94f2cee3658', + '9626816275585ac3443e7cddd1272c8652c23f1d', + '56dbd77df6e7034fad4699736ce200cd74c45a2f', + '4884e30b93b3c4c123a83154516196095f9e831e', + '1516361918bfd02ddd460489f438e153c918521c', + 'f0985ae3a3d69ba4ae8696120d38f4dd9cd39fc4', + 'a1c8f84670da9a3371bc5832e86c8d32826b2f2e', + '143b738a1e054cc48c925fd3605b39bca3dd5971', + '952dbc5e95b87538f3aac71306651f179bc2e90a', + '7ea92a937f5755b40ac3d99ed37c53b40359b0a2', + 'e473f25d192d5cb180d3718ed8e0e8c4f5db8245', + '05f157d8e8aa4b700b18e244f9813e0bf9fdf85a', + '1487afc813124abbeb0629d2172be0f01ccec3bf', + '0bfc37e2db0b10da237195561dd37dfe7ecdf923', + '8e098d2042ad9b9074f52cc06b89d6d4db5231dd', + '5c15e604c4207f52c8cf58fe21e63164c230e257', + '020ebeb40642bfb4bc3d9f6d28c098afc0a47481', + '510c312730b03cb91ab24e25ec2937cd4aaad767', + 'f6c6531bfadd0535894ae67be0eaa274d7ec7feb', + '25f384bd95e218f6ac37fcaca99ed40f36760d8c', + '70d0495ea46072bead82429fb405d60438036524', + 'fd7c4e2ef9f9ab457d9a15bf2fbbc6bebf0fe971', + 'aeb882df790ac1c25697954b2bf5cbb3a4ed06f9', + '31b9c54042b6cc1d1a388af1463e40baa9b37e7c', + '92c0f2f3239f1f61496997bd2cdc197ec51bd423', + 'c425ffbcc0c1ae0e0be7435f26f341f5ed4016c7', + '4a48d3f5c2058c9172c1a267beac6dac0b664d29', + '01e25f93b2e2b6d3ab6253619ee9ac66cc6568cc', + '079b201da1b30115767f4eb1393ca397f94ac947', + 'e84d35cb7f1b7ec84207edcd53c6ff16340147fa', + '1b982d94d3c62813053c998c0af83a3b1c9c4db2', + 'ce59b0c52f73407a8bcf95c604803dd8c9c30986', + '93a1b6e71cbd6b650254db1bbd9700d66716090e', + '935aba04a2468e2c09e10c64c6deabdd107892d1', + '9c51c1a119137cd17ed5ae09daa80c1cab6ac01d', + '71dcbdcfcbb548b5b8a54ce04f6290abea07b491', + 'c18996ca488753f714d36d4654715927c1d7f9c2', + '376a17e734d827276b8dd3fdc44077aa000b0f5a', + 'ec7c11ddc00bb8c3ddba97805811cd408261778f', + '21cc6c7696e56d550664548768e84f0f1e40615d', + '32e8ffd44b23769472abe62635005bf13538a167', + 'cfde892411994074f8c3b3127c5c493924909434', + '820321da50156ec53ea9afbb59bdc298262c1d0a', + '583f6a828d1723237b958b7b9a9249137f5efa76', + '70d5c5b51e7c9705dbf50c1ca7af49e4c033022b', + '7d332c8adf25a2179e031be9c20bc346d20aee1d', + '13807367799a8592ecbc0ae4cab683a8e213a741', + '4262bceff4420f24349944b3d9a02fd331ca9f34', + 'f1b6977e5ca6c115de6361737743b33f3f072ee3', + '086d2bacf441cef45ff15b5afe163d0b03a9f7ea', + '32de523ba228dd3f3159eb5a6cc07b6fd51f4dc0', + '00d1bc8dc16672f7059f24c1cc097bd4fc62b846', + '7a88e0eabf60af5ac61240fe60f8f08fa3e48ab4', + '8671dfd2f34302c1a4dcb4dd7361568a0bb23eba', + '2d2c1a3dc98ca868d1f2bfe76b8a1bb820857c5a', + 'c51f09467930d70e6c2955093fd8094cc102152a', + 'da4b6dd82dce4b22785e2a9699969d0b008a7623', + 'c9282bbb89d3f9f5f1d972a02f96a5f0f0f40df8', + '893e32a92321e288e2d5d9d5d0d06d274cdc9e03', + '0ddd797e39c5fe706ed4ee62f96becb792aee03a', + '2675ef3adf52ebf8a44ff5da4306c293dfa6f901', + '764cd0ccbe170699c7ea616d8172d621dde290fd', + '412bb061e08c29d46b84dbf0f07a82abb0887ec5', + 'f076bfc286216998c89ddb2c3e7926efaa2e961a', + 'aad3aeb7fdd9f04b0ffd1460252a50b7a84c6421', + '31b1710553d85d656a80e641c1091efc56a41258', + '1ed8d6c4385666f1f6f0d9aff2c468409674b318', + 'd12e201ba3f47c74e40e774ee48065fb0abf5ace', + '0f146009c7cf3f321af93dbc64c07459202904b7', + '2df2d0a3e95c6094d3a4b14cd313e95c407aff29', + '0e552bb2627f2ae7a0c7a780f3d59c3232789de2', + 'e15556732b56d86ddd459d704a69eeb3efe5ff85', + '358536c8512d0e7dbb479862ec3ad48fc129f16a', + '6b616b05e849a3578e2eeadf978f7a898ab4969f', + '6844d720c70fad79218f91661a7177b67b79a8d4', + 'de48c1fd2f803a4187a507d8de7b6606ba9a42b7', + '593b9b7e8f41f89188f9c4e9e71750f4b767e72b', + '3772507e49303f6db071f6361494deaafcbbf4cb', + '36147238d4f6a15cca48aa4b173496af41c79b43', + '2011df2d2ba878bee3edbdec893c1996816f49ab', + 'a96b79f19bf199153dd46932138530803bdc2a67', + 'a8910051dbbd27e9e2209d099984e94b96740328', + 'dfc74021a0743d5bbfc09fcb73970a6b280bb1d3', + 'd0dec51ee295fae711466a6642749217b6e48032', + '0e6d460ad5589ac6be39a93944ec08a699f89222', + '66d0098355a01201c8b390bc7a573d8ef99ad425', + 'cb770b3580d7e118e29c0a996d4f9840d9180efb', + 'dcd080312e011c799fe21ac67d56ee2bf84e6486', + '9b83833ba4b3432ddebb22c46061c811c04b3561', + '1742d08487674d3d63766de72fe48af6407f1560', + 'c73409178a35717a9a735aea942945fca53604fc', + 'da9cfea873671b7bacbe79ec331fc6073f50e1a2', + '222ebc0427471470cc3d6bbefd3f35dc32a9f388', + 'b21b72c1fb29f6dcb866cf7d148428d885ad42ea', + 'a77d47871d1b29b7aee4d1e4a646b06253475fe3', + 'af0f5d9e055d07c8308da7f6726562420ff0bb82', + '8f371083ec59446c7e481b13d70dc1411ecd73b9', + '2840e7087b8d57c860b8b6b3ba646b60ce293991', + 'b2bfb283db6af9f6d2c7b0daf27cbe5470b09913', + '748896c0e2d1388fb1dead2b7ee0f59a96e8af81', + 'cdd6dfd70b2e7984744f71cb7e9451fbf8bdd263', + '617886394bee35c359766fb4d9ae889b8fd39079', + '77912e1d53cec04f2343a754dd3ccb1853c5ea66', + '244521dec0e946eca601a520a324610add18350f', +]; + +export const GAMING = { + title: __('Gaming'), + route: '/$/gaming', + icon: ICONS.GAMING, + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${GAMING_CHANNEL_IDS.join( + ',' + )}`, + options: { + orderBy: ['release_time'], + pageSize: 12, + channelIds: GAMING_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const COMMUNITY_CHANNEL_IDS = [ + '90b566f5aca9c9a3b23b56cf6d75c07493737bc9', + '1aa69a21a8d7e7bab3f9366aba52936e3ddc5330', + '1cdb5d0bdcb484907d0a2fea4efdfe0153838642', + '55f552c153a6922798ce9f6d429b69c87c4c992a', + 'b516294f541a18ce00b71a60b2c82ad2f87ff78d', + 'ca43e7e24420ff5276694b8251643efd97271be1', + '297abfc0e8d63be217952ef20206a447de677d84', + '89985db232ec2a9a31dbd985196de817da223fe6', + '187bf3616318b4bfb85223fc40724c307696f0c6', + 'c7d2d5150a331e1696d95abb9a7b59d837c4e5a1', + 'e8b0d5e34558b8a852374fd40af1c0150a65504b', + 'ebdee96e9a17c9e5fe7627cc644eb75bd068a6ec', + 'e50f82e2236274c54af762a9c2b897646477ef62', + '797a528c49b6535560f7fd8222b121b0223287c8', + '935e7ed2c8b2a184ba2f39167f0201a74910235b', + 'a2e1bb1fed32c6a6290b679785dd31ca5c59cb5f', + 'c64f446ba359272f36c5b4abe02109d0a25bbbef', + '26b498d808f8ed9955caaf7e27cef31b20b2c87a', + '58b9503ee85cf5bb5268b4fd75644ea17b6c0d5d', + 'df961194a798cc76306b9290701130c592530fb6', + '0831bef6095a57ec440f626aac2a650a20282945', + '7109221d4047efb7e94b1d55c781757702a66f32', + 'f456460846ee417b9d8d333a5d71a5bd7867cc61', + 'ea1888b5758a23ff3c62b9a3fe07badb3e403cde', + '3fe68ad3da93065e35c37b14fbeef88b4b7785ed', + '4fa230f864cc4cd9c7d9962c042c49f35e913ffe', + '74e380497449d9eb13de9bc4038676097e4730fe', + 'c113df372c5bf801e6afebb700ce01347b211911', + 'e328468c130c232dcd282538b187e03dcfdbc13f', + 'e228ccf0ee188ef41372a8d7abdf9ce1c3408442', + 'c3f55aa9cb1d57828a468c7a6d02df42627a9524', + '08f31fe3fa6caa14799d7a7d1de8713553f5e8ee', + '5dfe76321bde01412ccad93a5a4ff48240c56bd6', + '32b91e45b29ca8d3af9ca9f9580601c53bd88974', + 'b22b497df412cd904c3be94e237a1f4693250ba8', + '5db02b3127911ac154fe951871c81c20d3902498', + 'f9711aef0efe74352c4315a2e2f9aba74d5c0ff5', + '4ad942982e43326c7700b1b6443049b3cfd82161', + 'c64f446ba359272f36c5b4abe02109d0a25bbbef', + '50d9c04b064b52249ceed889c55fff8db3dedb78', + 'a1c8f84670da9a3371bc5832e86c8d32826b2f2e', + '5c4370bfff3070458df198f6ba60c6eb1244c014', + 'b032695b52a78e0f5251b8d7f2f32183a5985d19', + 'a6a3b8eb73f184949add50257e1d1ad2fe2d8425', + '15f986a262fc6eff5774050c94d174c0533d505d', + '8e9ef4a69ef17507d1a3649573999a61e97f262c', + '2beb4ed8985dcc5b11334722abb024af1556415e', + 'b12e255e9f84d8b4ed86343b27676dccbc8b6d8b', + '50ebba2b06908f93d7963b1c6826cc0fd6104477', + '3c8b9829b664279c1ee285cb383c6d753a60c6c3', + '06980eeb4d2d1bc26ba2763177f1a71124d7dd78', + 'fd1aee1d4858ec2ef6ccc3e60504c76e9d774386', + 'f32f020e2885d763627a0c71dae86c7c33e1f693', + '58326307ddf6e9da5c4c09684f3885aad594a1c1', + 'be757c3bff18e553b9692930a7c1c85962cd69d9', + '273a2fa759f1a9f56b078633ea2f08fc2406002a', + '0739af4338a3e9c2307c4170107b30c0af1e1a1f', + 'a0c3cb01bc135a1135fcf710dd2b5f9c5d6cb2b7', + '5f22b6daf7204d73cf79d3ff0b46fc4fe237c7f7', + 'a72f265d045b18979d6a5ff785888f895b36cfd1', + '2e4c63a39e28e8e2bcac74debece9f7893fc3fe5', + '3583f5a570af6870504eea5a5f7afad6e1508508', + '6f0e439410756702b74876625cfffe2392bce31e', + '6b85c13a1b69740f548508ed8e50d757e7cf7b7e', + 'f399d873e0c37cf24de9569b5f22bbb30a5c6709', + 'e9267c855fce214463eff0b4fe9d6aa82bb66dd3', + 'b8a7f336f1aa1a6f459eb0dca1073cdeaf32527a', + 'ba79c80788a9e1751e49ad401f5692d86f73a2db', + 'ffdc62ac2f7549398d3aca9d2119e83d80d588d5', + 'ca1fd651c9d14bf2e5088bb2aa0146ee7aeb2ae0', + 'faed2b028a9b5a712d5180eaa6fd2aa619f941bc', + '87ef9ba36019f7f3bf217cf47511645893b13f2e', + '83725c7ee23bd4a8ca28a4fab0e313409def1dc7', + '0c00037101e2d9a14a7713ec057a49e794d26f35', + '52b08a58c4cbf86bb98e55685b6e778bb111e6fe', + '80f78c4b8591390758b9e6303eaf9087180444ad', + 'ac415179241e0cd8a14ed71175b759254d381137', + '38d5458f6e34d4b1e8fa1357408d08070e6a914c', + '88e2a1fe83f1efe3c07ef89b49d650645607553a', + '8903ed7a5937fffeedacc1ada02a8a391e877b11', + '968aadb8205becc89ecf808f82c3736f1d8ac8cd', + '851f7d55176669b219e1cbb2ebf76badaaf0665d', + '7243e2e5a6ef8a110f07d4f3b633c20c904e6527', + '056399cdf0860f95422f854ba95c1759f1d19564', + 'ab2d2fd8180b5568b6fbbf7d4dbce12335211e03', + 'c5724e280283cd985186af9a62494aae377daabd', + '9a5dfcb1a4b29c3a1598392d039744b9938b5a26', + '46be492ee0f56db11e005991c537c867a8682f77', + '4b602d7a3e268abb45951f623a109d2a131ab0ba', + '69611f33c5c77c00482b17d0be60b2919f7d96da', + '29193e9240a71a735639c66ee954e68414f11236', + '311a7f1387207afac9bcc513ae11e9f89399adf3', + 'a2aab4245eed5e00f6571e32ec822d93307e491c', + 'cfabf9da70f1d7ffa54c1a8f9ae4076512381104', + '44c49bbab8a3e9999f3ba9dee0186288b1d960a7', + '43f1605fb19313b7eb160ce346b22e2401f21149', + 'c3dd0196908978d9b82485e1debc5a3c03ca3c31', + '89c4cf244099918b1d3ed413df27d4216e97b499', + '5f1cac62e73072aed515557f1a608936a75b53b5', + 'e2d0317848b749498a13bf87874e0e8505041287', + '28a351f8fa72ae951f2e06abd9214dfae8d4ac83', + '0c978becd7fdcf88c24a78b9ce10b2d30e8a14d0', + '825aa21c8c0bda4ded3e69a69238763c8cfcc13b', + '0b3873a94928b67215f0b85d18a9bcb9283d91c8', + '64d370321db76980ca4e566654d09584c6b6cd70', + 'fee415182e20af42122bea8d1682dc6a4d99a0d6', + 'e3ecd1865a45a7b120c491a7e8bc7d5b43aae029', + 'f54fe46c7ae4b5a668073458bedff2d2ab3457e9', + '116d17f196e19681d00d19803d2674cd740391dc', + '9615932281a64a7888074d28b4fa3dc1d95027e2', + '020f649cca9ade46d4593441a97a86f2aaffb029', + '872150e55792c96fe337ff569b88e62b1c824f0c', + '0f8737fb29eca2d026b611c56ded69bed2f7897a', + 'd58b6a17d81b681a84e1194a218874ba11ce4fed', + '30ffa4c263d34ca38f6eb0e18925e872a3a32498', + 'd42f185080b262cbd45d55415692646aed999f76', + '9f376e4ad52ed33779647aca6fcb5b0a12e6c133', + '0a4e4d2994c5bf08f28aa8020ccc24e3ff2a2888', + '657a0b90a024535f7dd35ba927901f98a3ee7271', + '716b6d16d5b9b0c89f9bf9288bd9471bf5924082', + 'a9a4cf41533be5bce1d0440aeac0630e9f3d3730', + '43c099ed473395c40007da7628730d812a882628', + '4fd6950858377dc247952b6c94065273c8fd083e', + '3860625465ceb3098c2b7ab9e8ce567a288b5f4e', + '693d8aa643c30d4afb1a5e712ec57ac4ae699b26', + '718be0a9623a66a8c58dd5d9fd94aa214ad3e5cd', + 'c9f8ad37369bbd3c89322b1cbab0dd8f8b8b0925', + 'e29e2ced2f8b829f4a056b593ca673575ffada33', + 'fc824b22a178e7337c12a9b597c54e6678e42a6a', + 'f40f4a4546dabc9c47d9c75d0e5c0a9ba8581bec', + 'ba19d7e59726d73bba441460ed1345c57230cfa9', + '638f9e7b024efc24a14c161f8ccf4bacbcfda10b', + '61c93b69f7611337c3eae39ddbbc25acfa568112', + '44492321a13a0087c12394d4fb48c208ca6d4b27', + '2b606fa484378821f63b503c2bc4ba1a53d671f4', + 'c8a18f3d0c900e169c847df8390cac9993868475', + 'fa645836a9b694dc525289598cec9d7bc84eb968', + '261d1fb370fc73910642efddc3955a839d6cf674', + '38a83de67a246c72cd793104073968d7440e3509', + '1e2ba4bfa1a1812b71bffd7ae40d4ce3a61edb4a', + '1576023fb1869655ebdebd9e5b45dc4b06adbb91', + '4c4c9e44dd32e618ce56c7ca2e2e2b53e8027779', + '433882d9593c8b807b40bdd367afed545b6f5840', + '1dd1f89c9fec0450b8f446d88c8ca7eae806c54e', +]; + +export const COMMUNITY = { + title: __('Nice People'), + route: '/$/community', + icon: ICONS.COMMUNITY, + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${COMMUNITY_CHANNEL_IDS.join( + ',' + )}`, + options: { + orderBy: ['release_time'], + pageSize: 16, + channelIds: COMMUNITY_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const TECHNOLOGY_CHANNEL_IDS = [ + 'fdc3b71d6e99fe305863ac72721637d2ce49d1ad', + '8cbef9a7778b528a6183b4bb25bb748bf016b7ca', + '70d6386888708ce5559ca225120b2801f6e052bd', + '3e465c0163d8ab5635edb49e6f8f3933fa9cf42a', + '78d20123fdf5fbcfa2b2a5b71875a3e7e37a8d41', + '12f1f69fe070a79d171c5964e5a1053b26cb6df6', + '55f552c153a6922798ce9f6d429b69c87c4c992a', + '4f0686070ce0ec410ffa10bd46682f54b8d6d94c', + 'f33657a2fcbab2dc3ce555d5d6728f8758af7bc7', + '2f229d3ac26aa655c5123c29f1f7352403279ca3', + '8539673ff55e10a7ef2859d16194ad92c4d3a412', + '5af39f818f668d8c00943c9326c5201c4fe3c423', + '7b23cca3f49059f005e812be03931c81272eaac4', + '70645fd323c8730d7fab5528e4fa5883ecebe78a', + 'fba22d346111304c39b51ffc2740238a1449e5fd', + '3e465c0163d8ab5635edb49e6f8f3933fa9cf42a', + 'd9535951222dd7a1ff7f763872cb0df44f7962bf', + '3818d442f75be9c3685b6ad58e5ceb8569ade5ee', + '87b2669c65c60a36aa408f0177517a192db194a7', + '48c7ea8bc2c4adba09bf21a29689e3b8c2967522', + '2a6194792beac5130641e932b5ac6e5a99b5ca4f', + '6e29e20a77e1a6181e60ca19b0f83e8223416aa8', + '918be99daff84a69e1458cfabfda219f2a05271b', + '0afddbd02b7068c89d0bce77a0481875c159115f', + 'cda82633c939eb0d605c148277669cfe53cf2b72', + 'd2d3ac174a107b846f497be701e232539c4511f1', + 'a52425228572850f40651d2f8fe965a7d1f7d003', + 'feb61536c007cdf4faeeaab4876cb397feaf6b51', + '2305db36455aa0d18571015b9e9bd0950262aa0f', + 'a58a006307d0d579792dc677c27f2b6b0422b362', + 'fff58293070966ba11c7a978bc895320e80beab3', + '243b6f18093ff97c861d0568c7d3379606201a4b', + 'a9d289718f3f14e3d1fa8da7a7fcfdb6f40ae2d7', + '5af39f818f668d8c00943c9326c5201c4fe3c423', + '26c9b54d7e47dc8f7dc847821b26fce3009ee1a0', + 'fddb293b297417d753d0175be69a11e59b22ad57', + 'd95fff35a8bb853b9d80c93d7c0dee0b92beab3c', + '6a4fa1a68b92336e64006a4310cb160b07854329', + '6453f3d359787856c98f58dd13da44db282904de', + 'd0b97ba2a5eb024f4cc1d972b1c52896f37c32ed', + '70645fd323c8730d7fab5528e4fa5883ecebe78a', + 'ff9dddaef1f0c7938d7a4a170abef24c70e4cec7', + '6569758308f12a66001e28f5e6056cb84334e69c', + '5fbfcf517d3df749bd032a44c1946b2baa738ecb', + '74333143a3dcc001a5602aa524583fc75a013d75', + '0d4e104ffc0ff0a6c8701e67cf13760f4e0335a8', + '7b1c72ba903af4aecdc2595397a9cb91bb7f188d', + '6c412e4afc8258ab65d83900b46289d68abc3872', + 'fb364ef587872515f545a5b4b3182b58073f230f', + '589276465a23c589801d874f484cc39f307d7ec7', + 'ba79c80788a9e1751e49ad401f5692d86f73a2db', + '5b7c7a202201033d99e1be2930d290c127c0f4fe', + '7f9187dcb2a144c4d71cbab6756e3b1136db18b2', + 'a9d289718f3f14e3d1fa8da7a7fcfdb6f40ae2d7', + 'c5cd9b63e2ba0abc191feae48238f464baecb147', + '70d0495ea46072bead82429fb405d60438036524', + 'feb61536c007cdf4faeeaab4876cb397feaf6b51', + '0e2b5b4cf59e859860000ff123dc12a317ad416b', + '9a311e766fcbc69bd9f37fd068843a1a8b1aeb02', + 'c18996ca488753f714d36d4654715927c1d7f9c2', + '7a8954b2c09cb835f4b90be69fd4a5fc4f1b5f04', + '218bf13edaf0add8e60d88ab6a9d4584d7e0588a', + '6ce715e99c42b57eaa6303babbfc49386eeb1f61', + '3b807b82be6fadc0db4a057955766cea230839b9', + 'e8f68563d242f6ac9784dcbc41dd86c28a9391d6', + 'b0e489f986c345aef23c4a48d91cbcf5a6fdb9ac', + '4e17d248adc0128afe969c2e1327e10afd9cb921', + '56e86eb938c0b93beccde0fbaaead65755139a10', + '68044a0cf5ed7534872af5149d4e0c43a9a1d06a', + '8914f8e31ae94b9d9c2011b10b43d72283beae4f', + '5fc52291980268b82413ca4c0ace1b8d749f3ffb', + 'b9288432bd089c6f332145aab08a56eec155f307', + '4967034d0978c239b6e0bd4b1fea04d918c13a10', + 'edf63b41a82a93bad1d53b159af2e7e1fe119a5e', + '7d22a93f22e97ea2f2492ea290d044468067636d', + '5327b233d7128e8d806266f2f486a4e48ed325c1', + '5ca8477d50ac027e7cafc307139a58b34d01d658', + '63af489a47df203f0f7b95b88a9cffc6900d3929', + '5d9ea5ea1e333256ba3f18fce533b8cb26abc06a', + '61c4e8636704f2f38bbe88b1f30ef0d74d6c0f49', + '4a334a7388b6996b4148a33947f4bdbe324dce95', + '43fa9aec16c55f537e395f27b7185c0d812dd89a', + '2332c0df0bd5e046db04fe7e3e79f756d35a1523', + '1312bc5e063ba9a14b406b531a7fec1e55b3afaf', + '02bb55c11ab338ebeafcb6a9d24f99a3909f231a', + 'aa5544b6778d3620d57d8dcd3229c6c59354857a', + '35045f3a701c49be2d0494f08f90943f3d7c2edb', + '5c2667e322c6e56dc0c4097988bc778e677aa730', + '47c6a778ea4836b0987ccc4ce27b26d5f886ec1d', + '9f93bce4cfa3a73bebcded959684baf578c9d0c9', + '0adce5aabea4e6f8384a85d831397feefc9b403b', + '25feb42a7c5351597aa084210a59f348e9467ee9', + '51ea9ea2804269cb8e2a5951406a853aa5743913', + '10cba1b5805f62e8e49ce37c8d614cec7c3c3299', + '43a052ea087e5cd2d662005e2dedaaab816e9b26', + '3ce7a61f1171a99b00c123b9ed57d55e56baf119', + 'ff1dae8d9504ee6f5212ccb1b88d0f8d403f3d8e', + 'a30c5c8cb8faf78b7ad82118e8fd7039901a5a32', + '42594e750ad68e599703fbc6199788e8cabf98c0', + 'd840185c7b98eafe676ce0c6fc9128259335c8e7', + '67649f8e3edb907d455a1cf08f3e71a6da3c1205', + '364f077b4e9685aa2f25fbd424f8e1026e73c374', + 'c9f5527c1c802924e552715901fe52af3f2d4ccc', + 'b46144501bdcdcaae536b4a2d30250398225d0a5', + '8d497e7e96c789364c56aea7a35827d2dc1eea65', +]; + +export const TECHNOLOGY = { + title: __('Tech'), + route: '/$/tech', + icon: ICONS.TECH, + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${TECHNOLOGY_CHANNEL_IDS.join( + ',' + )}`, + options: { + orderBy: ['release_time'], + pageSize: 12, + channelIds: TECHNOLOGY_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const SCIENCE_CHANNEL_IDS = [ + '47c6a778ea4836b0987ccc4ce27b26d5f886ec1d', + '1bd0adfcf1c75bafc1ba3fc9b65a1a0470df6a91', + '7e1a7afadc8734b33a3e219f5668470715fb063d', + 'fb364ef587872515f545a5b4b3182b58073f230f', + 'c5cd9b63e2ba0abc191feae48238f464baecb147', + 'ba79c80788a9e1751e49ad401f5692d86f73a2db', + '589276465a23c589801d874f484cc39f307d7ec7', + 'fddb293b297417d753d0175be69a11e59b22ad57', + '5fbfcf517d3df749bd032a44c1946b2baa738ecb', + '43fa9aec16c55f537e395f27b7185c0d812dd89a', + '35045f3a701c49be2d0494f08f90943f3d7c2edb', + '55f552c153a6922798ce9f6d429b69c87c4c992a', + '87b2669c65c60a36aa408f0177517a192db194a7', + 'b79c5dee207f6429d677d65999aed96449e02092', + '5fc52291980268b82413ca4c0ace1b8d749f3ffb', + '07e4546674268fc0222b2ca22d31d0549dc217ee', + '545c86494bd5f7d9aeade8e58342e2a7ecf2f803', + 'de0fcd76d525b1db36f24523e75c28b542e92fa2', + '74333143a3dcc001a5602aa524583fc75a013d75', + '4967034d0978c239b6e0bd4b1fea04d918c13a10', + 'f54cc6a6a214ea183db11c47d7f5dc464e5bc9ef', + '4dbbe5e945ced9756327160b78c807007c2e9d72', + 'a52425228572850f40651d2f8fe965a7d1f7d003', + 'fa5b58aeba19dee98eb5c78cbc8c1d30f99acb8b', + '0d4e104ffc0ff0a6c8701e67cf13760f4e0335a8', + '6e83f36dfc16e44d8f48cd27d698ca49a6cd1402', + 'ef5eba855aabebe9292bfc10fa9b0884337ab52c', + 'c3cf3780c73279f8a20b764f2c7edea1cf380055', + '0e8d245734aab8c6825b6529a47d4cacfb3a53a8', + '918be99daff84a69e1458cfabfda219f2a05271b', + 'f82b1ddf6353454b9ba07d8c9cd758e9d4a6c148', + '46948b772a8d4eadeedbf2eadf0f6f37332cd7b8', + 'd0b97ba2a5eb024f4cc1d972b1c52896f37c32ed', + 'd4cf14c542ade693a79de689d24ec29ad73aee93', + '1feef57a100df13c84b2c03e2683498287e6781a', + '4fd4b60a7f00778ebbd150029164302fe84b7e56', + 'bd70f930e75b5886c3b66ace2d0ca31262d43a6f', + 'fe938863cb867c4e369d270bcfb062bb8281db2d', + '9826a0c0a781ce1beed3067202f8677a2740e3ba', + 'dd42c26d24c17ea326df2e4e4cb1f0e243f878a7', + '5327b233d7128e8d806266f2f486a4e48ed325c1', + 'b9288432bd089c6f332145aab08a56eec155f307', + '26c9b54d7e47dc8f7dc847821b26fce3009ee1a0', + '1df464dbb302ced815c61431a5548a273e6de8e1', + '2b6e925856bf5903be02ad1ea68469f084cd3b40', + '243b6f18093ff97c861d0568c7d3379606201a4b', + '5298af1ba35f126013e5d10217a7316f5c909e46', + '6768e311f5da5f286da963ff63026d88d215b747', + '8d45230d1c4e1e56dd3821bfbbe7d2af0369d8ed', + 'b1c26a3b6d4ce2b86ad011b2dd4d2bf8fa6c4d10', + 'b00669ef11a3d05d81d5e733674cb6234055cffd', + '264ad327b0927908b929f752ac96efe89f9450fa', + 'd6d17103b4aadd46c47236431eb7a96427ef98d7', + '9ed727bfe93f0b740bd46efcbbc86e839b77f17e', +]; + +export const SCIENCE = { + title: __('Lab'), + route: '/$/lab', + icon: ICONS.SCIENCE, + options: { + orderBy: ['release_time'], + pageSize: 12, + channelIds: SCIENCE_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const NEWS_CHANNEL_IDS = [ + '9614a4fcf9d91e4588eb512165e9c0475f857555', + '70e56234217f30317c0e67fd0eede6e82b74aea0', + '760da3ba3dd85830a843beaaed543a89b7a367e7', + 'c9da929d12afe6066acc89eb044b552f0d63782a', + 'ab524c5a1902d7a0f072ebc4d093a0e500704202', + '21aab81cf6b7f3eac2a5d934d35328560ba6fc9f', + '9b8a09c41c834f0d629cea4a083f86e4645feb0d', + '84edf7e474aba8a285d42a2ac1792801c5a2ca40', + '69b3c0cae5d30be16423b931c4552ed050a244b0', + '29d63cc4b23073bb5143b15bfa7872bbce073a34', + 'c1d55ae7b8a67e7a26d1511a462203173122e61d', + '5a7d88e0f510cdb2355bc4752bf530875d741491', + 'c101bac49ec048acca169fd6090e70f7488645b1', + '3e4240ee54f465db9e41435628ed8a5895c9a654', + '8b1c54250e1eb865f657d1b3d553d541a49ee4d8', + '276112ac14f42c7c9e05cf0a063be91b46905859', + 'd34376986bc857846993ff0aa750875bf7cf1b4a', + '840a5f8f0c5b7d1b87312f9915f7cd7a9283d572', + '2556ed1cab9d17f2a9392030a9ad7f5d138f11bd', + '19f251ac6d8f2990839173d932a47b1da62da484', + 'ddb27a205f0c5d17df73277367b6ef8256e0ed01', + 'e325ffd3e6b78f95f96a0e1fe4609539f62d0fe7', + '5462a0ced61fc3f86225908608872f0fda2cbc32', + 'c4b5c6d71ac9597b69c5559ca0f03691f58370a9', + '0475ed551e9513cbf81d2bec27488b9f5ea78d9a', + '8954add966e59c9cba98a143a3387f788a36d7be', + '79162cdb9d5ae8d7502089a38bdaaf81f902bf0c', + 'b57fb7641efdeb7af52bf96abb280d84c45587cc', + '833fa9985192d2a185806cad08d4dc9910b1b4ef', + '5e7a90800637e828ef5a58ec747a68840a4038d8', + '1576023fb1869655ebdebd9e5b45dc4b06adbb91', +]; + +export const NEWS = { + title: __('News'), + route: '/$/news', + icon: ICONS.NEWS, + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${NEWS_CHANNEL_IDS.join(',')}`, + options: { + orderBy: ['release_time'], + pageSize: 8, + channelIds: NEWS_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +export const FINCANCE_CHANNEL_IDS = [ + '29dd91896150d5383a5daef66247b9eb2523673f', + 'ac471128a5ed05b80365170b29997d860afa33b7', + '4284dc016523121128f4ffa45b983c24cc9136a3', + '74067192483939e846e1a8dd7b4bf1678ca5b0c5', + 'de7eda0eaaac4b29968af67d2d4b4ede54251699', + 'bfaafff1703523f4b3bcc9135d873fbbf5c9f138', + 'f0cb90bbe9ba6cf958a3fc2261a6743997e13551', + '1c9434d6111e27189fe023bb02a4b3e434209a62', + '7b6f7517f6b816827d076fa0eaad550aa315a4e7', + 'a938670c73275d9c6f1b70daf0bb1a5414e88c0b', + 'e50beec197c7d1cd2f9e6ce0f4176fee9d4949b9', + '26a76095b3add8301cc15641b5c5bbb3029f6e06', + 'f3c286bf1d9c440a479d5cea3e59fca67f4cc571', + 'a6bb2c7cfc4633f53941713bd0e6fe62c7646a6d', + 'ff80e24f41a2d706c70df9779542cba4715216c9', + '7a9c2e888ae46f26e8c3be98a0e38da1743f473c', + '4ee7cfaf1fc50a6df858ed0b99c278d633bccca9', + '4de2b2d04c7734a863f217951f66e265294f2c24', + '82679841636273c8b73abd7927b1d49769f146c9', + 'bd02ed31604feac8665f8694a10c95a7690d3088', + 'f08b8f02d8031a1ff114840857e7c40ebf50d1e9', + '680f16c5a8d0108239108cfa96505d40601ae7a2', + '9f298dbb29674fe4959b0aadb7d8d88a69331892', + 'a181bdf7ced0a7c9159906c27f71f80309944bfa', + '8e5c01528ba74261ee8b1410214eacd12c27fdc8', + 'd300bbae741c7cd8f90ae964698f24e2b4251635', + 'b96d57fbb37ef76cb9a3a9d4a6dbfa4f427b5108', + '0fc0fa43e7d5c95e701add3e71358b979a5f4f9d', + '8e83a89570b0b24b28d540c88594adc3a19d1483', + '11836afd765f135d7ce51b66d2af6b30aafa687a', + 'd5606663658481f3452cf6ba8eabf77451d0ce07', + 'ebc4214424cfa683a7046e1f794fea1e44788d84', + '0edad9e2b95e178ace67dddcd3c01085930b296f', + '29cc7f6081268eaa5b3f2946e0cd0b952a94812c', + 'c38f46508c77fc375898ef97de979e18c3ea82f0', + '828174a6adcdeee74de5211db1d006716aa54d07', + '3247ca511495e06cc5e4868ba6c3dfb5d0f10008', + '4da85b12244839d6368b9290f1619ff9514ab2a8', + '50ad846a4b1543b847bf3fdafb7b45f6b2f5844c', + '9ca6e62b04b6355ee15fb6a00588358f3847e37a', + '3134864016d0be0b831dbe9a3048242d00a42475', + 'ad4dca5a634a89bd5410c009665e9daaa444c7b3', + 'd7ea64522a3b7fccb182cd275fc8556d512a720f', + '579563946c1123a67f6dd417c2ed19d24c135a80', + '20ba0b4afe9ca31d7fb37742519a987fad31fb12', + '53d679982abe3f17ea2691b37fc757518d0417bf', + '9d09d9e9545bd4de0a55625afa43cd8ca123d10d', + '40c36948f0da072dcba3e4833e90f71e16de78be', + '84342ae85d216d5ffc0ef149a123aae649d5c253', + '19a07e69b84ffa9db9324e237ed28fd8ec33f9c5', + '7a095af7b427efdaf2577ef264c72741c760fc31', + 'b48863a2f343c3d1869cf02691862f1cee3ac2dd', + '060940e41973d4f7f16d72a2733138e931c35f41', + 'af9547659bec3fd214c7ddc9f0c7fc86bf5adfff', + 'c5b0b17838df2f6c31162f64d55f60f34ae8bfc6', + 'b325961c50c986f2022313220e5b98da9b0004bc', + 'fb7209b5061de8776bfe1df0795a8a2588ef4108', + '0a1d9a8240df94ac365e49e4311c44d38b819dcb', + 'b1923f8c6a01f69c6980b193a2d8d2c47a354328', + 'a403ce7eff82b75a530dffd211ddc69847be4425', + '7a95519d4beba3b7657713fb020f180af807d309', + 'a0692fd6261e2c77827321705056838fb49fc951', + '8972a1bd06de5186e5e89292b05aac8aaa817791', + 'e73639dee45f76c8ca8275d29792d64b4a4525f4', + '04784caee866e077d46ad9f34a14cc84a289b80c', + '96ede5667bc4533ace8cfcbde4f33aa9fe1ae5f5', + 'bca584685bd0fb5760f46e6a060a1b2c68c99b46', + 'd208b2677c169a4d90b4c97250dde031da6d3c10', + 'd6e2ff2e46822d5ad9a9df89549f7ea5a6bf5255', + 'e06849202121aa4ceac73da1b581a552197e5661', + '726fde854edc58a0d385aad398bf416a0316d748', + 'c62ee910262e0a126181dc454b0556a174bfb120', + '87ef9ba36019f7f3bf217cf47511645893b13f2e', + '699b0ad4913a31b3315b6f1c722685dfaff426a8', + 'cda9c4e92f19d6fe0764524a2012056e06ca2055', + 'a21c363963e130dc77cd62bbde39e745206654c0', + '77ac5ad623a63fd526b8c67f5fceb95ccbfdcbb1', + '9576be30de21b3b755828314d6ccbbaa3334f43a', + '1e86953852705f11b8f01ed62eb3d4cfa3443597', + '97f52bb1d107c32527326650fce8b5a652707227', + 'c9a3cf2234af0888b6be256adc13613d76e74fe2', + '097591ffe010e7b9b1641b967f9f94e66c683acf', + '9b6d9cc2783d1586763370231e7fac4b3b97ec70', + 'd000b2fec8d46d9a7cb9a12ee3cf598d11b24918', + '6977c53ca432fd49f5d441a08da01930eb74401d', + '183638482bda8aca67a57f577c927c0649062c9e', + 'ca1727de1ccaa2de2fb74fefdfcf3d630f3cae12', + '3fda836a92faaceedfe398225fb9b2ee2ed1f01a', + 'c6571998fb5cef27fde1fd5831882a6c6816cadb', + '4474b52aeb12e69607aa34656d1d7a351e8a09d0', +]; + +export const FINANCE = { + title: __('Finance 2.0'), + icon: ICONS.FINANCE, + route: '/$/finance', + link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${FINCANCE_CHANNEL_IDS.join( + ',' + )}`, + options: { + orderBy: ['release_time'], + pageSize: 8, + channelIds: FINCANCE_CHANNEL_IDS, + limitClaimsPerChannel: 3, + releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, + }, +}; + +const WILD_WEST = { + title: 'Wild West', + link: `/$/${PAGES.WILD_WEST}`, + icon: ICONS.WILD_WEST, }; export default function GetHomePageRowData( @@ -32,104 +1255,6 @@ export default function GetHomePageRowData( let rowData: Array<RowDataItem> = []; const individualTagDataItems: Array<RowDataItem> = []; - const YOUTUBER_CHANNEL_IDS = [ - 'fb364ef587872515f545a5b4b3182b58073f230f', - '589276465a23c589801d874f484cc39f307d7ec7', - 'ba79c80788a9e1751e49ad401f5692d86f73a2db', - 'b6e207c5f8c58e7c8362cd05a1501bf2f5b694f2', - 'c5724e280283cd985186af9a62494aae377daabd', - '243b6f18093ff97c861d0568c7d3379606201a4b', - '5b7c7a202201033d99e1be2930d290c127c0f4fe', - 'c9da929d12afe6066acc89eb044b552f0d63782a', - '89985db232ec2a9a31dbd985196de817da223fe6', - '187bf3616318b4bfb85223fc40724c307696f0c6', - 'aa3db8d2145340e26597b88fbb6d0e7ff09786be', - 'a9d289718f3f14e3d1fa8da7a7fcfdb6f40ae2d7', - '9a5dfcb1a4b29c3a1598392d039744b9938b5a26', - '0b998b98a2b9a88d9519739f99f2c74c95e3fc22', - '46be492ee0f56db11e005991c537c867a8682f77', - 'c5cd9b63e2ba0abc191feae48238f464baecb147', - '4b602d7a3e268abb45951f623a109d2a131ab0ba', - 'd25ae97a1516f5700fc717152b885f33da47f12b', - '8f4fecfc836ea33798ee3e5cef56926fa54e2cf9', - '8671dfd2f34302c1a4dcb4dd7361568a0bb23eba', - 'b9288432bd089c6f332145aab08a56eec155f307', - '87b13b074936b1f42a7c6758c7c2995f58c602e7', - '25f384bd95e218f6ac37fcaca99ed40f36760d8c', - '02c020b2fab7dd1fbd175c3b22947688c0a219e5', - '57dbc8fdc4d062e2824d8550861b380203539099', - '4e17d248adc0128afe969c2e1327e10afd9cb921', - '760da3ba3dd85830a843beaaed543a89b7a367e7', - '5a1b164d0a2e7adf1db08d7363ea1cb06c30cd74', - 'c9da929d12afe6066acc89eb044b552f0d63782a', - '113515e893b8186595595e594ecc410bae50c026', - '5fbfcf517d3df749bd032a44c1946b2baa738ecb', - '74333143a3dcc001a5602aa524583fc75a013d75', - '0d4e104ffc0ff0a6c8701e67cf13760f4e0335a8', - 'b924ac36b7499591f7929d9c4903de79b07b1cb9', - '13edd7e7e2fbaf845699cf2f8f0b1c095bacb05f', - '7b1c72ba903af4aecdc2595397a9cb91bb7f188d', - '6c0bf1fed2705d675da950a94e4af004ec975a06', - 'f33657a2fcbab2dc3ce555d5d6728f8758af7bc7', - '26c9b54d7e47dc8f7dc847821b26fce3009ee1a0', - '1516361918bfd02ddd460489f438e153c918521c', - 'd468989b4668bce7452fc3434a6dc7ba7d799378', - 'a1c8f84670da9a3371bc5832e86c8d32826b2f2e', - '70e56234217f30317c0e67fd0eede6e82b74aea0', - '7a88e0eabf60af5ac61240fe60f8f08fa3e48ab4', - '2f229d3ac26aa655c5123c29f1f7352403279ca3', - '7ea92a937f5755b40ac3d99ed37c53b40359b0a2', - '96ede5667bc4533ace8cfcbde4f33aa9fe1ae5f5', - '5097b175c4c58c431424ce3b60901de6ae650127', - '32de523ba228dd3f3159eb5a6cc07b6fd51f4dc0', - 'cdb6fe516afe08618b91a754f92412e7f98a8a62', - '1e9f582c2df798228e8583fe1101fee551487d4b', - 'b032695b52a78e0f5251b8d7f2f32183a5985d19', - 'c042155dfcb5c813345248bff18a62d0f585718e', - '294f5c164da5ac9735658b2d58d8fee6745dfc45', - '07e4546674268fc0222b2ca22d31d0549dc217ee', - '1487afc813124abbeb0629d2172be0f01ccec3bf', - 'ac471128a5ed05b80365170b29997d860afa33b7', - 'c101bac49ec048acca169fd6090e70f7488645b1', - 'c9282bbb89d3f9f5f1d972a02f96a5f0f0f40df8', - '9576be30de21b3b755828314d6ccbbaa3334f43a', - 'b12e255e9f84d8b4ed86343b27676dccbc8b6d8b', - '50ebba2b06908f93d7963b1c6826cc0fd6104477', - '84342ae85d216d5ffc0ef149a123aae649d5c253', - '80f78c4b8591390758b9e6303eaf9087180444ad', - '086d2bacf441cef45ff15b5afe163d0b03a9f7ea', - '5af39f818f668d8c00943c9326c5201c4fe3c423', - '057053dfb657aaa98553e2c544b06e1a2371557e', - 'fd1aee1d4858ec2ef6ccc3e60504c76e9d774386', - '930fc43ca7bae20d4706543e97175d1872b0671f', - 'e715c457b4a3e51214b62f49f05303bba4ee5be9', - 'ebf5bc6842638cefcf66904522ac96231ea7a9d8', - '1f9bb08bfa2259629f4aaa9ed40f97e9a41b6fa1', - 'ac415179241e0cd8a14ed71175b759254d381137', - '8e098d2042ad9b9074f52cc06b89d6d4db5231dd', - '149c4686ff0792b8d68dac1f17b6273a85628d34', - '199eba05b6ecccab919e26a0cb7dacd544f25700', - '6569758308f12a66001e28f5e6056cb84334e69c', - 'e50f82e2236274c54af762a9c2b897646477ef62', - '7e1a7afadc8734b33a3e219f5668470715fb063d', - 'ff80e24f41a2d706c70df9779542cba4715216c9', - 'e8f68563d242f6ac9784dcbc41dd86c28a9391d6', - ]; - - const YOUTUBE_CREATOR_ROW = { - title: __('CableTube Escape Artists'), - link: `/$/${PAGES.DISCOVER}?${CS.CLAIM_TYPE}=${CS.CLAIM_STREAM}&${CS.CHANNEL_IDS_KEY}=${YOUTUBER_CHANNEL_IDS.join( - ',' - )}`, - options: { - claimType: ['stream'], - orderBy: ['release_time'], - pageSize: getPageSize(12), - channelIds: YOUTUBER_CHANNEL_IDS, - limitClaimsPerChannel: 1, - releaseTime: `>${Math.floor(moment().subtract(1, 'months').startOf('week').unix())}`, - }, - }; if (followedTags.length) { followedTags.forEach((tag: Tag) => { @@ -152,6 +1277,7 @@ export default function GetHomePageRowData( icon: ICONS.SUBSCRIBE, options: { orderBy: ['release_time'], + streamTypes: CS.FILE_TYPES, releaseTime: subscribedChannels.length > 20 ? `>${Math.floor(moment().subtract(6, 'months').startOf('week').unix())}` @@ -164,104 +1290,26 @@ export default function GetHomePageRowData( }, }; - const TOP_CONTENT_TODAY = { - title: __('Top Content from Today'), - link: `/$/${PAGES.DISCOVER}?${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TOP}&${CS.FRESH_KEY}=${CS.FRESH_DAY}`, - options: { - pageSize: getPageSize(showPersonalizedChannels || showPersonalizedTags ? 4 : 8), - orderBy: ['effective_amount'], - claimType: ['stream'], - limitClaimsPerChannel: 2, - releaseTime: `>${Math.floor(moment().subtract(1, 'day').startOf('day').unix())}`, - }, - }; - - const TOP_CHANNELS = { - title: __('Top Channels On LBRY'), - link: `/$/${PAGES.DISCOVER}?claim_type=channel&${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TOP}&${CS.FRESH_KEY}=${CS.FRESH_ALL}`, - options: { - orderBy: ['effective_amount'], - claimType: ['channel'], - }, - }; - - // const TRENDING_CLASSICS = { - // title: __('Trending Classics'), - // link: `/$/${PAGES.DISCOVER}?${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TRENDING}&${CS.FRESH_KEY}=${CS.FRESH_WEEK}`, - // options: { - // pageSize: getPageSize(4), - // claimType: ['stream'], - // limitClaimsPerChannel: 1, - // releaseTime: `<${Math.floor( - // moment() - // .subtract(6, 'month') - // .startOf('day') - // .unix() - // )}`, - // }, - // }; - - // const TRENDING_ON_LBRY = { - // title: __('Trending On LBRY'), - // link: `/$/${PAGES.DISCOVER}`, - // options: { - // pageSize: showPersonalizedChannels || showPersonalizedTags ? 4 : 8, - // }, - // }; - - const TRENDING_FOR_TAGS = { - title: __('Trending For Your Tags'), - link: `/$/${PAGES.TAGS_FOLLOWING}`, - icon: ICONS.TAG, - - options: { - pageSize: getPageSize(4), - tags: followedTags.map((tag) => tag.name), - claimType: ['stream'], - limitClaimsPerChannel: 2, - }, - }; - - const LATEST_FROM_LBRY = { - title: __('Latest From @lbry'), - link: `/@lbry:3f`, - options: { - orderBy: ['release_time'], - pageSize: getPageSize(4), - channelIds: ['3fda836a92faaceedfe398225fb9b2ee2ed1f01a'], - }, - }; - - const LATEST_FROM_LBRYCAST = { - title: __('Latest From @lbrycast'), - link: `/@lbrycast:4`, - options: { - orderBy: ['release_time'], - pageSize: getPageSize(4), - channelIds: ['4c29f8b013adea4d5cca1861fb2161d5089613ea'], - }, - }; - + // rowData.push(PRIMARY_CONTENT); if (showPersonalizedChannels) rowData.push(RECENT_FROM_FOLLOWING); - if (showPersonalizedTags && !showIndividualTags) rowData.push(TRENDING_FOR_TAGS); - if (showPersonalizedTags && showIndividualTags) { - individualTagDataItems.forEach((item: RowDataItem) => { - rowData.push(item); - }); - } - - if (!authenticated) { - rowData.push(YOUTUBE_CREATOR_ROW); - } - - rowData.push(TOP_CONTENT_TODAY); - - // rowData.push(TRENDING_ON_LBRY); - - rowData.push(LATEST_FROM_LBRY); - rowData.push(LATEST_FROM_LBRYCAST); - - if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS); + rowData.push(ENLIGHTENMENT); + // rowData.push(PRIMARY_CONTENT_2); + rowData.push(GAMING); + rowData.push(COMMUNITY); + rowData.push(SCIENCE); + rowData.push(TECHNOLOGY); return rowData; } + +export const EXTRA_SIDEBAR_LINKS = [ + ENLIGHTENMENT, + GAMING, + SCIENCE, + TECHNOLOGY, + NEWS, + FINANCE, + COMMUNITY, + WILD_WEST, + RABBIT_HOLE, +]; diff --git a/static/app-strings.json b/static/app-strings.json index bcc98dd17..7a6319878 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -858,7 +858,6 @@ "Tag selection": "Tag selection", "Select some tags to help us show you interesting things.": "Select some tags to help us show you interesting things.", "You are currently following %followingCount% tags": "You are currently following %followingCount% tags", - "You are currently following %followingCount% tag": "You are currently following %followingCount% tag", "Back": "Back", "Experimental Transcoding": "Experimental Transcoding", "A Folder containing FFmpeg": "A Folder containing FFmpeg", @@ -1417,6 +1416,7 @@ "Never fear though, there are tons of ways to earn %lbc%. You can earn or purchase %lbc%, or you can have your friends send you some.": "Never fear though, there are tons of ways to earn %lbc%. You can earn or purchase %lbc%, or you can have your friends send you some.", "gaming, comedy, educational": "gaming, comedy, educational", "A channel is required to comment on %SITE_NAME%": "A channel is required to comment on %SITE_NAME%", + "A channel is required to comment on lbry.tv": "A channel is required to comment on lbry.tv", "A welcome bonus and thank you for your contribution to content freedom.": "A welcome bonus and thank you for your contribution to content freedom.", "You earned %lbc% new user reward.": "You earned %lbc% LBC new user reward.", "Just press play on something. Anything at all. Yep, even that one. Everybody's doing it.": "Just press play on something. Anything at all. Yep, even that one. Everybody's doing it.", diff --git a/static/img/favicon.png b/static/img/favicon.png index 4570d2248..20e725d6e 100644 Binary files a/static/img/favicon.png and b/static/img/favicon.png differ diff --git a/static/img/lbry-favicon.png b/static/img/lbry-favicon.png new file mode 100644 index 000000000..4570d2248 Binary files /dev/null and b/static/img/lbry-favicon.png differ diff --git a/ui/analytics.js b/ui/analytics.js index 32d6bdd94..41c5dde4a 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -26,10 +26,10 @@ if (isProduction) { // @endif type Analytics = { - error: string => Promise<any>, + error: (string) => Promise<any>, sentryError: ({} | string, {}) => Promise<any>, pageView: (string, ?string) => void, - setUser: Object => void, + setUser: (Object) => void, toggleInternal: (boolean, ?boolean) => void, apiLogView: (string, string, string, ?number, ?() => void) => Promise<any>, apiLogPublish: (ChannelClaim | StreamClaim) => void, @@ -39,6 +39,9 @@ type Analytics = { playerStartedEvent: (?boolean) => void, videoFetchDuration: (string, number) => void, videoStartEvent: (string, number) => void, + adsFetchedEvent: () => void, + adsReceivedEvent: (any) => void, + adsErrorEvent: (any) => void, videoBufferEvent: ( StreamClaim, { @@ -55,9 +58,9 @@ type Analytics = { emailVerifiedEvent: () => void, rewardEligibleEvent: () => void, startupEvent: () => void, - purchaseEvent: number => void, - readyEvent: number => void, - openUrlEvent: string => void, + purchaseEvent: (number) => void, + readyEvent: (number) => void, + openUrlEvent: (string) => void, }; type LogPublishParams = { @@ -75,8 +78,8 @@ if (window.localStorage.getItem(SHARE_INTERNAL) === 'true') internalAnalyticsEna // @endif const analytics: Analytics = { - error: message => { - return new Promise(resolve => { + error: (message) => { + return new Promise((resolve) => { if (internalAnalyticsEnabled && isProduction) { return Lbryio.call('event', 'desktop_error', { error_message: message }).then(() => { resolve(true); @@ -87,9 +90,9 @@ const analytics: Analytics = { }); }, sentryError: (error, errorInfo) => { - return new Promise(resolve => { + return new Promise((resolve) => { if (internalAnalyticsEnabled && isProduction) { - Sentry.withScope(scope => { + Sentry.withScope((scope) => { scope.setExtras(errorInfo); const eventId = Sentry.captureException(error); resolve(eventId); @@ -114,7 +117,7 @@ const analytics: Analytics = { MatomoInstance.trackPageView(params); } }, - setUser: userId => { + setUser: (userId) => { if (internalAnalyticsEnabled && userId) { window._paq.push(['setUserId', String(userId)]); // @if TARGET='app' @@ -188,7 +191,7 @@ const analytics: Analytics = { } }, - apiSyncTags: params => { + apiSyncTags: (params) => { if (internalAnalyticsEnabled && isProduction) { Lbryio.call('content_tags', 'sync', params); } @@ -238,12 +241,21 @@ const analytics: Analytics = { }); } }, - playerLoadedEvent: embedded => { + playerLoadedEvent: (embedded) => { sendMatomoEvent('Player', 'Loaded', embedded ? 'embedded' : 'onsite'); }, - playerStartedEvent: embedded => { + playerStartedEvent: (embedded) => { sendMatomoEvent('Player', 'Started', embedded ? 'embedded' : 'onsite'); }, + adsFetchedEvent: () => { + sendMatomoEvent('Media', 'AdsFetched'); + }, + adsReceivedEvent: (response) => { + sendMatomoEvent('Media', 'AdsReceived', JSON.stringify(response)); + }, + adsErrorEvent: (response) => { + sendMatomoEvent('Media', 'AdsError', JSON.stringify(response)); + }, tagFollowEvent: (tag, following) => { sendMatomoEvent('Tag', following ? 'Tag-Follow' : 'Tag-Unfollow', tag); }, @@ -316,7 +328,7 @@ analytics.pageView( // Listen for url changes and report // This will include search queries -history.listen(location => { +history.listen((location) => { const { pathname, search } = location; const page = `${pathname}${search}`; diff --git a/ui/component/app/view.jsx b/ui/component/app/view.jsx index d6150edf2..c8bba563a 100644 --- a/ui/component/app/view.jsx +++ b/ui/component/app/view.jsx @@ -399,12 +399,12 @@ function App(props: Props) { {/* @if TARGET='web' */} <YoutubeWelcome /> - {!shouldHideNag && <OpenInAppLink uri={uri} />} + {false && !shouldHideNag && <OpenInAppLink uri={uri} />} {!shouldHideNag && <NagContinueFirstRun />} {(lbryTvApiStatus === STATUS_DEGRADED || lbryTvApiStatus === STATUS_FAILING) && !shouldHideNag && ( <NagDegradedPerformance onClose={() => setLbryTvApiStatus(STATUS_OK)} /> )} - {lbryTvApiStatus === STATUS_OK && showAnalyticsNag && !shouldHideNag && ( + {false && lbryTvApiStatus === STATUS_OK && showAnalyticsNag && !shouldHideNag && ( <NagDataCollection onClose={handleAnalyticsDismiss} /> )} {/* @endif */} diff --git a/ui/component/channelContent/view.jsx b/ui/component/channelContent/view.jsx index b026bc2d9..02c2ec51f 100644 --- a/ui/component/channelContent/view.jsx +++ b/ui/component/channelContent/view.jsx @@ -132,10 +132,12 @@ function ChannelContent(props: Props) { {claim && claimsInChannel > 0 ? ( <ClaimListDiscover + hideLivestreamClaims showHiddenByUser={viewHiddenChannels} forceShowReposts tileLayout={tileLayout} uris={searchResults} + streamType={CS.CONTENT_ALL} channelIds={[claim.claim_id]} feeAmount={CS.FEE_AMOUNT_ANY} defaultOrderBy={CS.ORDER_BY_NEW} diff --git a/ui/component/channelThumbnail/spaceman.png b/ui/component/channelThumbnail/spaceman.png new file mode 100644 index 000000000..4300ae1c1 Binary files /dev/null and b/ui/component/channelThumbnail/spaceman.png differ diff --git a/ui/component/channelThumbnail/view.jsx b/ui/component/channelThumbnail/view.jsx index d3af5c508..45f31e5d1 100644 --- a/ui/component/channelThumbnail/view.jsx +++ b/ui/component/channelThumbnail/view.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { parseURI } from 'lbry-redux'; import classnames from 'classnames'; -import Gerbil from './gerbil.png'; +import Spaceman from './spaceman.png'; import FreezeframeWrapper from 'component/fileThumbnail/FreezeframeWrapper'; import ChannelStakedIndicator from 'component/channelStakedIndicator'; @@ -79,7 +79,7 @@ function ChannelThumbnail(props: Props) { <img alt={__('Channel profile picture')} className="channel-thumbnail__default" - src={!thumbError && thumbnailPreview ? thumbnailPreview : Gerbil} + src={!thumbError && thumbnailPreview ? thumbnailPreview : Spaceman} onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. /> )} @@ -91,7 +91,7 @@ function ChannelThumbnail(props: Props) { <img alt={__('Channel profile picture')} className="channel-thumbnail__custom" - src={!thumbError ? thumbnailPreview || thumbnail : Gerbil} + src={!thumbError ? thumbnailPreview || thumbnail : Spaceman} onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. /> )} diff --git a/ui/component/claimList/view.jsx b/ui/component/claimList/view.jsx index 9bd614953..9b557cbcd 100644 --- a/ui/component/claimList/view.jsx +++ b/ui/component/claimList/view.jsx @@ -38,6 +38,7 @@ type Props = { renderActions?: (Claim) => ?Node, searchInLanguage: boolean, hideMenu?: boolean, + hideLivestreamClaims?: boolean, }; export default function ClaimList(props: Props) { @@ -63,6 +64,7 @@ export default function ClaimList(props: Props) { renderActions, searchInLanguage, hideMenu, + hideLivestreamClaims, } = props; const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW); @@ -101,7 +103,14 @@ export default function ClaimList(props: Props) { return tileLayout && !header ? ( <section className="claim-grid"> {urisLength > 0 && - uris.map((uri) => <ClaimPreviewTile key={uri} uri={uri} showHiddenByUser={showHiddenByUser} />)} + uris.map((uri) => ( + <ClaimPreviewTile + key={uri} + uri={uri} + showHiddenByUser={showHiddenByUser} + hideLivestreamClaims={hideLivestreamClaims} + /> + ))} {!timedOut && urisLength === 0 && !loading && <div className="empty main--empty">{empty || noResultMsg}</div>} {timedOut && timedOutMessage && <div className="empty main--empty">{timedOutMessage}</div>} </section> @@ -157,6 +166,7 @@ export default function ClaimList(props: Props) { renderActions={renderActions} showUserBlocked={showHiddenByUser} showHiddenByUser={showHiddenByUser} + hideLivestreamClaims={hideLivestreamClaims} customShouldHide={(claim: StreamClaim) => { // Hack to hide spee.ch thumbnail publishes // If it meets these requirements, it was probably uploaded here: diff --git a/ui/component/claimListDiscover/view.jsx b/ui/component/claimListDiscover/view.jsx index 18562ea59..42a9d4c07 100644 --- a/ui/component/claimListDiscover/view.jsx +++ b/ui/component/claimListDiscover/view.jsx @@ -23,7 +23,7 @@ type Props = { personalView: boolean, doToggleTagFollowDesktop: (string) => void, meta?: Node, - showNsfw: boolean, + // showNsfw: boolean, hideReposts: boolean, history: { action: string, push: (string) => void, replace: (string) => void }, location: { search: string, pathname: string }, @@ -66,6 +66,9 @@ type Props = { searchInLanguage: boolean, scrollAnchor?: string, showHiddenByUser?: boolean, + limitClaimsPerChannel?: number, + releaseTime?: string, + hideLivestreamClaims?: boolean, }; function ClaimListDiscover(props: Props) { @@ -78,7 +81,7 @@ function ClaimListDiscover(props: Props) { loading, meta, channelIds, - showNsfw, + // showNsfw, hideReposts, history, location, @@ -93,8 +96,8 @@ function ClaimListDiscover(props: Props) { claimType, pageSize, defaultClaimType, - streamType, - defaultStreamType, + streamType = CS.FILE_VIDEO, + defaultStreamType = CS.FILE_VIDEO, freshness, defaultFreshness = CS.FRESH_WEEK, renderProperties, @@ -113,8 +116,11 @@ function ClaimListDiscover(props: Props) { forceShowReposts = false, languageSetting, searchInLanguage, + limitClaimsPerChannel, + releaseTime, scrollAnchor, showHiddenByUser = false, + hideLivestreamClaims, } = props; const didNavigateForward = history.action === 'PUSH'; const { search } = location; @@ -153,12 +159,12 @@ function ClaimListDiscover(props: Props) { const durationParam = urlParams.get(CS.DURATION_KEY) || null; const channelIdsInUrl = urlParams.get(CS.CHANNEL_IDS_KEY); const channelIdsParam = channelIdsInUrl ? channelIdsInUrl.split(',') : channelIds; - const feeAmountParam = urlParams.get('fee_amount') || feeAmount; + const feeAmountParam = urlParams.get('fee_amount') || feeAmount || CS.FEE_AMOUNT_ONLY_FREE; const originalPageSize = pageSize || CS.PAGE_SIZE; const dynamicPageSize = isLargeScreen ? Math.ceil(originalPageSize * (3 / 2)) : originalPageSize; const historyAction = history.action; - let orderParam = orderBy || urlParams.get(CS.ORDER_BY_KEY) || defaultOrderBy; + let orderParam = orderBy || urlParams.get(CS.ORDER_BY_KEY) || defaultOrderBy || orderParamEntry; if (!orderParam) { if (historyAction === 'POP') { @@ -202,6 +208,7 @@ function ClaimListDiscover(props: Props) { fee_amount?: string, has_source?: boolean, has_no_source?: boolean, + limit_claims_per_channel?: number, } = { page_size: dynamicPageSize, page, @@ -213,7 +220,7 @@ function ClaimListDiscover(props: Props) { not_channel_ids: // If channelIdsParam were passed in, we don't need not_channel_ids !channelIdsParam ? mutedAndBlockedChannelIds : [], - not_tags: !showNsfw ? MATURE_TAGS : [], + not_tags: MATURE_TAGS, order_by: orderParam === CS.ORDER_BY_TRENDING ? CS.ORDER_BY_TRENDING_VALUE @@ -226,6 +233,10 @@ function ClaimListDiscover(props: Props) { options.has_source = true; } + if (limitClaimsPerChannel) { + options.limit_claims_per_channel = limitClaimsPerChannel; + } + if (feeAmountParam && claimType !== CS.CLAIM_CHANNEL) { options.fee_amount = feeAmountParam; } @@ -255,7 +266,9 @@ function ClaimListDiscover(props: Props) { options.reposted_claim_id = repostedClaimId; } - if (claimType !== CS.CLAIM_CHANNEL) { + if (releaseTime) { + options.release_time = releaseTime; + } else if (claimType !== CS.CLAIM_CHANNEL) { if (orderParam === CS.ORDER_BY_TOP && freshnessParam !== CS.FRESH_ALL) { options.release_time = `>${Math.floor(moment().subtract(1, freshnessParam).startOf('hour').unix())}`; } else if (orderParam === CS.ORDER_BY_NEW || orderParam === CS.ORDER_BY_TRENDING) { @@ -333,9 +346,25 @@ function ClaimListDiscover(props: Props) { const hasMatureTags = tagsParam && tagsParam.split(',').some((t) => MATURE_TAGS.includes(t)); const claimSearchCacheQuery = createNormalizedClaimSearchKey(options); - const claimSearchResult = claimSearchByQuery[claimSearchCacheQuery]; + let claimSearchResult = claimSearchByQuery[claimSearchCacheQuery]; const claimSearchResultLastPageReached = claimSearchByQueryLastPageReached[claimSearchCacheQuery]; + // uncomment to fix an item on a page + // const fixUri = 'lbry://@corbettreport#0/lbryodysee#5'; + // if ( + // orderParam === CS.ORDER_BY_NEW && + // claimSearchResult && + // claimSearchResult.length > 2 && + // window.location.pathname === '/$/rabbithole' + // ) { + // if (claimSearchResult.indexOf(fixUri) !== -1) { + // claimSearchResult.splice(claimSearchResult.indexOf(fixUri), 1); + // } else { + // claimSearchResult.pop(); + // } + // claimSearchResult.splice(2, 0, fixUri); + // } + const [prevOptions, setPrevOptions] = React.useState(null); if (!isJustScrollingToNewPage(prevOptions, options)) { @@ -455,7 +484,7 @@ function ClaimListDiscover(props: Props) { claimType={claimType} streamType={streamType} defaultStreamType={defaultStreamType} - feeAmount={feeAmount} + // feeAmount={feeAmount} orderBy={orderBy} defaultOrderBy={defaultOrderBy} hideAdvancedFilter={hideAdvancedFilter} @@ -492,6 +521,7 @@ function ClaimListDiscover(props: Props) { includeSupportAction={includeSupportAction} injectedItem={injectedItem} showHiddenByUser={showHiddenByUser} + hideLivestreamClaims={hideLivestreamClaims} /> {loading && ( <div className="claim-grid"> @@ -520,6 +550,7 @@ function ClaimListDiscover(props: Props) { includeSupportAction={includeSupportAction} injectedItem={injectedItem} showHiddenByUser={showHiddenByUser} + hideLivestreamClaims={hideLivestreamClaims} /> {loading && new Array(dynamicPageSize).fill(1).map((x, i) => <ClaimPreview key={i} placeholder="loading" />)} </div> diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 31dc7908f..eb952e9e8 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -127,6 +127,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => { const abandoned = !isResolvingUri && !claim; const shouldHideActions = hideActions || type === 'small' || type === 'tooltip'; const canonicalUrl = claim && claim.canonical_url; + let isValid = false; if (uri) { try { @@ -277,7 +278,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => { </div> )} {/* @endif */} - {!isRepost && !isChannelUri && ( + {!isRepost && !isChannelUri && !isLivestream && ( <div className="claim-preview__file-property-overlay"> <FileProperties uri={contentUri} small /> </div> diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js index aaa3ec5a0..aba27e1ac 100644 --- a/ui/component/claimPreviewTile/index.js +++ b/ui/component/claimPreviewTile/index.js @@ -8,6 +8,7 @@ import { doFileGet, makeSelectChannelForClaimUri, makeSelectClaimIsNsfw, + makeSelectClaimHasSource, } from 'lbry-redux'; import { selectMutedChannels } from 'redux/selectors/blocked'; import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc'; @@ -25,6 +26,7 @@ const select = (state, props) => ({ blockedChannelUris: selectMutedChannels(state), showMature: selectShowMatureContent(state), isMature: makeSelectClaimIsNsfw(props.uri)(state), + isLivestream: !makeSelectClaimHasSource(props.uri)(state), }); const perform = (dispatch) => ({ diff --git a/ui/component/claimPreviewTile/view.jsx b/ui/component/claimPreviewTile/view.jsx index 6532842a8..f75dff3a4 100644 --- a/ui/component/claimPreviewTile/view.jsx +++ b/ui/component/claimPreviewTile/view.jsx @@ -40,6 +40,8 @@ type Props = { isMature: boolean, showMature: boolean, showHiddenByUser?: boolean, + hideLivestreamClaims?: boolean, + isLivestream: boolean, }; function ClaimPreviewTile(props: Props) { @@ -60,6 +62,8 @@ function ClaimPreviewTile(props: Props) { isMature, showMature, showHiddenByUser, + hideLivestreamClaims, + isLivestream, } = props; const isRepost = claim && claim.repost_channel_url; const shouldFetch = claim === undefined; @@ -137,7 +141,7 @@ function ClaimPreviewTile(props: Props) { shouldHide = blockedChannelUris.some((blockedUri) => blockedUri === claim.permanent_url); } - if (shouldHide) { + if (shouldHide || (isLivestream && hideLivestreamClaims)) { return null; } diff --git a/ui/component/claimTilesDiscover/view.jsx b/ui/component/claimTilesDiscover/view.jsx index dffc3b704..226da2f37 100644 --- a/ui/component/claimTilesDiscover/view.jsx +++ b/ui/component/claimTilesDiscover/view.jsx @@ -1,12 +1,12 @@ // @flow import { ENABLE_NO_SOURCE_CLAIMS } from 'config'; +import * as CS from 'constants/claim_search'; import React from 'react'; import { createNormalizedClaimSearchKey, MATURE_TAGS } from 'lbry-redux'; import ClaimPreviewTile from 'component/claimPreviewTile'; import { useHistory } from 'react-router'; type Props = { - prefixUris?: Array<string>, uris: Array<string>, doClaimSearch: ({}) => void, showNsfw: boolean, @@ -32,6 +32,7 @@ type Props = { timestamp?: string, feeAmount?: string, limitClaimsPerChannel?: number, + streamTypes?: Array<string>, }; function ClaimTilesDiscover(props: Props) { @@ -49,16 +50,18 @@ function ClaimTilesDiscover(props: Props) { releaseTime, languages, claimType, - prefixUris, timestamp, feeAmount, limitClaimsPerChannel, fetchingClaimSearchByQuery, + streamTypes, + // pin, } = props; const { location } = useHistory(); const urlParams = new URLSearchParams(location.search); const feeAmountInUrl = urlParams.get('fee_amount'); - const feeAmountParam = feeAmountInUrl || feeAmount; + const feeAmountParam = feeAmountInUrl || feeAmount || CS.FEE_AMOUNT_ONLY_FREE; + const options: { page_size: number, no_totals: boolean, @@ -89,6 +92,7 @@ function ClaimTilesDiscover(props: Props) { channel_ids: channelIds || [], not_channel_ids: [], order_by: orderBy || ['trending_group', 'trending_mixed'], + stream_types: streamTypes || [CS.FILE_VIDEO], }; if (!ENABLE_NO_SOURCE_CLAIMS && (!claimType || claimType === 'stream')) { @@ -129,12 +133,23 @@ function ClaimTilesDiscover(props: Props) { } const claimSearchCacheQuery = createNormalizedClaimSearchKey(options); - const uris = (prefixUris || []).concat(claimSearchByQuery[claimSearchCacheQuery] || []); + const uris = claimSearchByQuery[claimSearchCacheQuery] || []; + // Don't use the query from createNormalizedClaimSearchKey for the effect since that doesn't include page & release_time const optionsStringForEffect = JSON.stringify(options); const isLoading = fetchingClaimSearchByQuery[claimSearchCacheQuery]; const shouldPerformSearch = !isLoading && uris.length === 0; + // const fixUri = 'lbry://@ElectroBOOM#9/remove-your-mustache#9'; + // if (pin && uris && uris.length > 2 && window.location.pathname === '/') { + // if (uris.indexOf(fixUri) !== -1) { + // uris.splice(uris.indexOf(fixUri), 1); + // } else { + // uris.pop(); + // } + // uris.splice(2, 0, fixUri); + // } + React.useEffect(() => { if (shouldPerformSearch) { const searchOptions = JSON.parse(optionsStringForEffect); diff --git a/ui/component/commentCreate/view.jsx b/ui/component/commentCreate/view.jsx index 53f20d0d8..31d5676ad 100644 --- a/ui/component/commentCreate/view.jsx +++ b/ui/component/commentCreate/view.jsx @@ -7,7 +7,7 @@ import { FormField, Form } from 'component/common/form'; import Button from 'component/button'; import SelectChannel from 'component/selectChannel'; import usePersistedState from 'effects/use-persisted-state'; -import { FF_MAX_CHARS_IN_COMMENT } from 'constants/form-field'; +import { FF_MAX_CHARS_IN_COMMENT, FF_MAX_CHARS_IN_LIVESTREAM_COMMENT } from 'constants/form-field'; import { useHistory } from 'react-router'; import type { ElementRef } from 'react'; import emoji from 'emoji-dictionary'; @@ -33,11 +33,15 @@ type Props = { parentId: string, isReply: boolean, isPostingComment: boolean, - activeChannel: string, activeChannelClaim: ?ChannelClaim, - livestream?: boolean, + bottom: boolean, + onSubmit: (string, string) => void, + livestream: boolean, + authenticated: boolean, + embed?: boolean, toast: (string) => void, claimIsMine: boolean, + commentingEnabled: boolean, }; export function CommentCreate(props: Props) { @@ -53,12 +57,20 @@ export function CommentCreate(props: Props) { parentId, isPostingComment, activeChannelClaim, + onSubmit, + bottom, livestream, + authenticated, + embed, toast, claimIsMine, + commentingEnabled, } = props; const buttonref: ElementRef<any> = React.useRef(); - const { push } = useHistory(); + const { + push, + location: { pathname }, + } = useHistory(); const { claim_id: claimId } = claim; const [commentValue, setCommentValue] = React.useState(''); const [lastCommentTime, setLastCommentTime] = React.useState(); @@ -80,7 +92,7 @@ export function CommentCreate(props: Props) { function altEnterListener(e: SyntheticKeyboardEvent<*>) { const KEYCODE_ENTER = 13; - if ((e.ctrlKey || e.metaKey) && e.keyCode === KEYCODE_ENTER) { + if ((livestream || e.ctrlKey || e.metaKey) && e.keyCode === KEYCODE_ENTER) { e.preventDefault(); buttonref.current.click(); } @@ -101,9 +113,7 @@ export function CommentCreate(props: Props) { : (lastCommentTime - Date.now()) / 1000 + COMMENT_SLOW_MODE_SECONDS; if (livestream && !claimIsMine && timeUntilCanComment > 0) { - toast( - __('Slowmode is on. You can comment again in %time% seconds.', { time: Math.ceil(timeUntilCanComment) }) - ); + toast(__('Slowmode is on. You can comment again in %time% seconds.', { time: Math.ceil(timeUntilCanComment) })); return; } @@ -112,6 +122,10 @@ export function CommentCreate(props: Props) { setCommentValue(''); setLastCommentTime(Date.now()); + if (onSubmit) { + onSubmit(commentValue, activeChannelClaim.name); + } + if (onDoneReplying) { onDoneReplying(); } @@ -126,9 +140,18 @@ export function CommentCreate(props: Props) { useEffect(() => setCharCount(commentValue.length), [commentValue]); - if (!hasChannels) { + if (!commentingEnabled || !hasChannels) { return ( - <div role="button" onClick={() => push(`/$/${PAGES.CHANNEL_NEW}`)}> + <div + role="button" + onClick={() => + embed + ? window.open(`https://odysee.com/$/${PAGES.AUTH}?redirect=/$/${PAGES.LIVESTREAM}`) + : authenticated + ? push(`/$/${PAGES.CHANNEL_NEW}?redirect=${pathname}`) + : push(`/$/${PAGES.AUTH}?redirect=${pathname}`) + } + > <FormField type="textarea" name={'comment_signup_prompt'} @@ -136,7 +159,7 @@ export function CommentCreate(props: Props) { label={isFetchingChannels ? __('Comment') : undefined} /> <div className="section__actions"> - <Button disabled button="primary" label={__('Post --[button to submit something]--')} requiresAuth={IS_WEB} /> + <Button disabled button="primary" label={__('Post --[button to submit something]--')} /> </div> </div> ); @@ -148,6 +171,7 @@ export function CommentCreate(props: Props) { className={classnames('comment__create', { 'comment__create--reply': isReply, 'comment__create--nested-reply': isNested, + 'comment__create--bottom': bottom, })} > <FormField @@ -171,7 +195,7 @@ export function CommentCreate(props: Props) { charCount={charCount} onChange={handleCommentChange} autoFocus={isReply} - textAreaMaxLength={FF_MAX_CHARS_IN_COMMENT} + textAreaMaxLength={livestream ? FF_MAX_CHARS_IN_LIVESTREAM_COMMENT : FF_MAX_CHARS_IN_COMMENT} /> {livestream && hasChannels && ( <div className="livestream__emoji-actions"> @@ -190,7 +214,11 @@ export function CommentCreate(props: Props) { ))} </div> )} - <div className="section__actions section__actions--no-margin"> + <div + className={classnames('section__actions', { + 'section__actions--no-margin': !livestream, + })} + > <Button ref={buttonref} button="primary" diff --git a/ui/component/commentReactions/view.jsx b/ui/component/commentReactions/view.jsx index 4dc2c50d9..8be8d97c7 100644 --- a/ui/component/commentReactions/view.jsx +++ b/ui/component/commentReactions/view.jsx @@ -77,7 +77,7 @@ export default function CommentReactions(props: Props) { <Button requiresAuth={IS_WEB} title={__('Upvote')} - icon={ICONS.UPVOTE} + icon={myReacts.includes(REACTION_TYPES.LIKE) ? ICONS.FIRE_ACTIVE : ICONS.FIRE} className={classnames('comment__action', { 'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.LIKE), })} @@ -87,7 +87,7 @@ export default function CommentReactions(props: Props) { <Button requiresAuth={IS_WEB} title={__('Downvote')} - icon={ICONS.DOWNVOTE} + icon={myReacts.includes(REACTION_TYPES.DISLIKE) ? ICONS.SLIME_ACTIVE : ICONS.SLIME} className={classnames('comment__action', { 'comment__action--active': myReacts && myReacts.includes(REACTION_TYPES.DISLIKE), })} diff --git a/ui/component/common/card.jsx b/ui/component/common/card.jsx index 414426263..f3b06deb1 100644 --- a/ui/component/common/card.jsx +++ b/ui/component/common/card.jsx @@ -20,6 +20,7 @@ type Props = { defaultExpand?: boolean, nag?: Node, smallTitle?: boolean, + onClick?: () => void, }; export default function Card(props: Props) { @@ -37,12 +38,20 @@ export default function Card(props: Props) { smallTitle = false, defaultExpand, nag, + onClick, } = props; const [expanded, setExpanded] = useState(defaultExpand); const expandable = defaultExpand !== undefined; return ( - <section className={classnames(className, 'card')}> + <section + className={classnames(className, 'card')} + onClick={() => { + if (onClick) { + onClick(); + } + }} + > {(title || subtitle) && ( <div className={classnames('card__header--between', { diff --git a/ui/component/fileActions/view.jsx b/ui/component/fileActions/view.jsx index a52970e3e..c77a4ee04 100644 --- a/ui/component/fileActions/view.jsx +++ b/ui/component/fileActions/view.jsx @@ -26,6 +26,7 @@ type Props = { myChannels: ?Array<ChannelClaim>, doToast: ({ message: string }) => void, clearPlayingUri: () => void, + hideRepost?: boolean, isLivestreamClaim: boolean, }; @@ -42,6 +43,7 @@ function FileActions(props: Props) { myChannels, clearPlayingUri, doToast, + hideRepost, isLivestreamClaim, } = props; const { @@ -83,23 +85,25 @@ function FileActions(props: Props) { const lhsSection = ( <> - {ENABLE_FILE_REACTIONS && <FileReactions uri={uri} />} + {ENABLE_FILE_REACTIONS && <FileReactions uri={uri} livestream={isLivestreamClaim} />} <ClaimSupportButton uri={uri} fileAction /> - <Button - button="alt" - className="button--file-action" - icon={ICONS.REPOST} - label={ - claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost') - } - description={__('Repost')} - requiresAuth={IS_WEB} - onClick={handleRepostClick} - /> + {!hideRepost && ( + <Button + button="alt" + className="button--file-action" + icon={ICONS.REPOST} + label={ + claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost') + } + description={__('Repost')} + requiresAuth={IS_WEB} + onClick={handleRepostClick} + /> + )} <Button className="button--file-action" icon={ICONS.SHARE} - label={__('Share')} + label={isMobile ? undefined : __('Share')} title={__('Share')} onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable })} /> diff --git a/ui/component/fileDescription/view.jsx b/ui/component/fileDescription/view.jsx index 3cacdeed1..d9a90b4bc 100644 --- a/ui/component/fileDescription/view.jsx +++ b/ui/component/fileDescription/view.jsx @@ -50,7 +50,7 @@ function FileDescription(props: Props) { <FileDetails uri={uri} /> </div> - <div className="section__actions--between"> + <div className="card__bottom-actions"> {expanded ? ( <Button button="link" label={__('Less')} onClick={() => setExpanded(!expanded)} /> ) : ( diff --git a/ui/component/fileReactions/view.jsx b/ui/component/fileReactions/view.jsx index 08ce9a569..d72823df7 100644 --- a/ui/component/fileReactions/view.jsx +++ b/ui/component/fileReactions/view.jsx @@ -1,4 +1,5 @@ // @flow +import * as REACTION_TYPES from 'constants/reactions'; import * as ICONS from 'constants/icons'; import React from 'react'; import classnames from 'classnames'; @@ -8,25 +9,51 @@ import NudgeFloating from 'component/nudgeFloating'; type Props = { claim: StreamClaim, - doFetchReactions: string => void, - doReactionLike: string => void, - doReactionDislike: string => void, + doFetchReactions: (string) => void, + doReactionLike: (string) => void, + doReactionDislike: (string) => void, uri: string, likeCount: number, dislikeCount: number, myReaction: ?string, + livestream?: boolean, }; function FileReactions(props: Props) { - const { claim, uri, doFetchReactions, doReactionLike, doReactionDislike, likeCount, dislikeCount } = props; + const { + claim, + uri, + doFetchReactions, + doReactionLike, + doReactionDislike, + myReaction, + likeCount, + dislikeCount, + livestream, + } = props; const claimId = claim && claim.claim_id; const channel = claim && claim.signing_channel && claim.signing_channel.name; React.useEffect(() => { - if (claimId) { + function fetchReactions() { doFetchReactions(claimId); } - }, [claimId, doFetchReactions]); + + let fetchInterval; + if (claimId) { + fetchReactions(); + + if (livestream) { + fetchInterval = setInterval(fetchReactions, 10000); + } + } + + return () => { + if (fetchInterval) { + clearInterval(fetchInterval); + } + }; + }, [claimId, doFetchReactions, livestream]); return ( <> @@ -41,20 +68,46 @@ function FileReactions(props: Props) { title={__('I like this')} requiresAuth={IS_WEB} authSrc="filereaction_like" - className={classnames('button--file-action')} - label={formatNumberWithCommas(likeCount, 0)} + className={classnames('button--file-action', { 'button--fire': myReaction === REACTION_TYPES.LIKE })} + label={ + <> + {myReaction === REACTION_TYPES.LIKE && ( + <> + <div className="button__fire-glow" /> + <div className="button__fire-particle1" /> + <div className="button__fire-particle2" /> + <div className="button__fire-particle3" /> + <div className="button__fire-particle4" /> + <div className="button__fire-particle5" /> + <div className="button__fire-particle6" /> + </> + )} + {formatNumberWithCommas(likeCount, 0)} + </> + } iconSize={18} - icon={ICONS.UPVOTE} + icon={myReaction === REACTION_TYPES.LIKE ? ICONS.FIRE_ACTIVE : ICONS.FIRE} onClick={() => doReactionLike(uri)} /> <Button requiresAuth={IS_WEB} authSrc={'filereaction_dislike'} title={__('I dislike this')} - className={classnames('button--file-action')} - label={formatNumberWithCommas(dislikeCount, 0)} + className={classnames('button--file-action', { 'button--slime': myReaction === REACTION_TYPES.DISLIKE })} + label={ + <> + {myReaction === REACTION_TYPES.DISLIKE && ( + <> + <div className="button__slime-stain" /> + <div className="button__slime-drop1" /> + <div className="button__slime-drop2" /> + </> + )} + {formatNumberWithCommas(dislikeCount, 0)} + </> + } iconSize={18} - icon={ICONS.DOWNVOTE} + icon={myReaction === REACTION_TYPES.DISLIKE ? ICONS.SLIME_ACTIVE : ICONS.SLIME} onClick={() => doReactionDislike(uri)} /> </> diff --git a/ui/component/fileSubtitle/view.jsx b/ui/component/fileSubtitle/view.jsx index ee2403ddb..e9f5f72c0 100644 --- a/ui/component/fileSubtitle/view.jsx +++ b/ui/component/fileSubtitle/view.jsx @@ -23,8 +23,8 @@ function FileSubtitle(props: Props) { <FileViewCount uri={uri} /> )} </div> - - <FileActions uri={uri} /> + { /* did I need these params? */ } + <FileActions uri={uri} hideRepost={livestream} livestream={livestream} /> </div> ); } diff --git a/ui/component/fileViewCount/view.jsx b/ui/component/fileViewCount/view.jsx index fa0d2aab5..dff4143f5 100644 --- a/ui/component/fileViewCount/view.jsx +++ b/ui/component/fileViewCount/view.jsx @@ -1,10 +1,11 @@ // @flow +import { SIMPLE_SITE } from 'config'; import React, { useEffect } from 'react'; import HelpLink from 'component/common/help-link'; type Props = { claim: ?StreamClaim, - fetchViewCount: string => void, + fetchViewCount: (string) => void, uri: string, viewCount: string, }; @@ -12,7 +13,6 @@ type Props = { function FileViewCount(props: Props) { const { claim, uri, fetchViewCount, viewCount } = props; const claimId = claim && claim.claim_id; - useEffect(() => { if (claimId) { fetchViewCount(claimId); @@ -24,7 +24,7 @@ function FileViewCount(props: Props) { return ( <span className="media__subtitle--centered"> {viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view')} - <HelpLink href="https://lbry.com/faq/views" /> + {!SIMPLE_SITE && <HelpLink href="https://lbry.com/faq/views" />} </span> ); } diff --git a/ui/component/fileViewerEmbeddedTitle/view.jsx b/ui/component/fileViewerEmbeddedTitle/view.jsx index e97b56e73..da5f00df0 100644 --- a/ui/component/fileViewerEmbeddedTitle/view.jsx +++ b/ui/component/fileViewerEmbeddedTitle/view.jsx @@ -5,7 +5,8 @@ import FilePrice from 'component/filePrice'; import { formatLbryUrlForWeb } from 'util/url'; import { withRouter } from 'react-router'; import { URL } from 'config'; -import * as ICONS from 'constants/icons'; +import OdyseeLogo from 'component/header/odysee_logo.png'; +import OdyseeLogoWithText from 'component/header/odysee_white.png'; type Props = { uri: string, @@ -36,7 +37,10 @@ function FileViewerEmbeddedTitle(props: Props) { {...contentLinkProps} /> <div className="file-viewer__embedded-info"> - <Button className="file-viewer__overlay-logo" icon={ICONS.LBRY} aria-label={__('Home')} {...lbryLinkProps} /> + <Button className="file-viewer__overlay-logo" aria-label={__('Home')} {...lbryLinkProps}> + <img src={OdyseeLogo} className=" mobile-only" /> + <img src={OdyseeLogoWithText} className=" mobile-hidden" /> + </Button> {isInApp && <FilePrice uri={uri} />} </div> </div> diff --git a/ui/component/header/view.jsx b/ui/component/header/view.jsx index 0af8f65f4..2c4b0f5d9 100644 --- a/ui/component/header/view.jsx +++ b/ui/component/header/view.jsx @@ -19,6 +19,8 @@ import ChannelThumbnail from 'component/channelThumbnail'; import { remote } from 'electron'; import { IS_MAC } from 'component/app/view'; // @endif +import OdyseeLogoWithWhiteText from './odysee_white.png'; +import OdyseeLogoWithText from './odysee.png'; type Props = { user: ?User, @@ -86,8 +88,8 @@ const Header = (props: Props) => { sidebarOpen, setSidebarOpen, isAbsoluteSideNavHidden, - user, hideCancel, + user, activeChannelClaim, } = props; const isMobile = useIsMobile(); @@ -98,7 +100,7 @@ const Header = (props: Props) => { const isPwdResetPage = history.location.pathname.includes(PAGES.AUTH_PASSWORD_RESET); const hasBackout = Boolean(backout); const { backLabel, backNavDefault, title: backTitle, simpleTitle: simpleBackTitle } = backout || {}; - const notificationsEnabled = (user && user.experimental_ui) || false; + // const notificationsEnabled = (user && user.experimental_ui) || false; // fix this const livestreamEnabled = (ENABLE_NO_SOURCE_CLAIMS && user && user.experimental_ui) || false; const activeChannelUrl = activeChannelClaim && activeChannelClaim.permanent_url; @@ -233,19 +235,12 @@ const Header = (props: Props) => { icon={ICONS.MENU} onClick={() => setSidebarOpen(!sidebarOpen)} > - {isAbsoluteSideNavHidden && isMobile && notificationsEnabled && <NotificationBubble />} + {isAbsoluteSideNavHidden && isMobile && <NotificationBubble />} </Button> </span> )} <Button - className="header__navigation-item header__navigation-item--lbry" - // @if TARGET='app' - label={'LBRY'} - // @endif - // @if TARGET='web' - label={LOGO_TITLE} // eslint-disable-line - // @endif - icon={ICONS.LBRY} + className="header__navigation-item header__navigation-item--lbry header__navigation-item--button-mobile" onClick={() => { if (history.location.pathname === '/') window.location.reload(); }} @@ -255,7 +250,12 @@ const Header = (props: Props) => { }} // @endif {...homeButtonNavigationProps} - /> + > + <img + src={currentTheme === 'light' ? OdyseeLogoWithText : OdyseeLogoWithWhiteText} + className="header__odysee" + /> + </Button> {!authHeader && ( <div className="header__center"> @@ -272,7 +272,7 @@ const Header = (props: Props) => { <HeaderMenuButtons authenticated={authenticated} - notificationsEnabled={notificationsEnabled} + notificationsEnabled history={history} handleThemeToggle={handleThemeToggle} currentTheme={currentTheme} @@ -425,6 +425,10 @@ function HeaderMenuButtons(props: HeaderMenuButtonProps) { <Icon aria-hidden icon={ICONS.CHANNEL} /> {__('New Channel')} </MenuItem> + <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.YOUTUBE_SYNC}`)}> + <Icon aria-hidden icon={ICONS.YOUTUBE} /> + {__('Sync YouTube Channel')} + </MenuItem> {livestreamEnabled && ( <MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.LIVESTREAM}`)}> diff --git a/ui/component/livestreamFeed/index.js b/ui/component/livestreamFeed/index.js new file mode 100644 index 000000000..46923101e --- /dev/null +++ b/ui/component/livestreamFeed/index.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import { makeSelectClaimForUri } from 'lbry-redux'; +import LivestreamFeed from './view'; + +const select = (state, props) => ({ + claim: makeSelectClaimForUri(props.uri)(state), +}); + +export default connect(select)(LivestreamFeed); diff --git a/ui/component/livestreamFeed/view.jsx b/ui/component/livestreamFeed/view.jsx new file mode 100644 index 000000000..116a1ae6a --- /dev/null +++ b/ui/component/livestreamFeed/view.jsx @@ -0,0 +1,38 @@ +// @flow +import { BITWAVE_USERNAME, BITWAVE_EMBED_URL } from 'constants/livestream'; +import React from 'react'; +import FileTitleSection from 'component/fileTitleSection'; +import LivestreamComments from 'component/livestreamComments'; + +type Props = { + uri: string, + claim: ?StreamClaim, + activeViewers: number, +}; + +export default function LivestreamFeed(props: Props) { + const { claim, uri, activeViewers } = props; + + if (!claim) { + return null; + } + + return ( + <> + <div className="section card-stack"> + <div className="file-render file-render--video livestream"> + <div className="file-viewer"> + <iframe + src={`${BITWAVE_EMBED_URL}/${BITWAVE_USERNAME}?skin=odysee&autoplay=1`} + scrolling="no" + allowFullScreen + /> + </div> + </div> + + <FileTitleSection uri={uri} livestream activeViewers={activeViewers} /> + </div> + <LivestreamComments uri={uri} /> + </> + ); +} diff --git a/ui/component/livestreamLink/view.jsx b/ui/component/livestreamLink/view.jsx index 86fc85413..39a1eaf13 100644 --- a/ui/component/livestreamLink/view.jsx +++ b/ui/component/livestreamLink/view.jsx @@ -13,7 +13,7 @@ export default function LivestreamLink(props: Props) { const { channelClaim } = props; const [livestreamClaim, setLivestreamClaim] = React.useState(false); const [isLivestreaming, setIsLivestreaming] = React.useState(false); - const livestreamChannelId = channelClaim.claim_id || ''; // TODO: fail in a safer way, probably + const livestreamChannelId = (channelClaim && channelClaim.claim_id) || ''; // TODO: fail in a safer way, probably React.useEffect(() => { if (livestreamChannelId) { diff --git a/ui/component/notificationBubble/view.jsx b/ui/component/notificationBubble/view.jsx index b8ac0edb6..f3d060030 100644 --- a/ui/component/notificationBubble/view.jsx +++ b/ui/component/notificationBubble/view.jsx @@ -5,14 +5,12 @@ import classnames from 'classnames'; type Props = { unseenCount: number, inline: boolean, - user: ?User, }; export default function NotificationHeaderButton(props: Props) { - const { unseenCount, inline = false, user } = props; - const notificationsEnabled = user && user.experimental_ui; + const { unseenCount, inline = false } = props; - if (unseenCount === 0 || !notificationsEnabled) { + if (unseenCount === 0) { return null; } diff --git a/ui/component/notificationHeaderButton/view.jsx b/ui/component/notificationHeaderButton/view.jsx index 18dc409a0..9c19e4116 100644 --- a/ui/component/notificationHeaderButton/view.jsx +++ b/ui/component/notificationHeaderButton/view.jsx @@ -19,9 +19,8 @@ export default function NotificationHeaderButton(props: Props) { // notifications, // fetching, doSeeAllNotifications, - user, + // user, } = props; - const notificationsEnabled = user && user.experimental_ui; const { push } = useHistory(); function handleMenuClick() { @@ -32,10 +31,6 @@ export default function NotificationHeaderButton(props: Props) { push(`/$/${PAGES.NOTIFICATIONS}`); } - if (!notificationsEnabled) { - return null; - } - return ( <Button onClick={handleMenuClick} diff --git a/ui/component/page/view.jsx b/ui/component/page/view.jsx index 4fe613deb..bc55d0eb5 100644 --- a/ui/component/page/view.jsx +++ b/ui/component/page/view.jsx @@ -1,5 +1,6 @@ // @flow import type { Node } from 'react'; +import * as PAGES from 'constants/pages'; import React, { Fragment } from 'react'; import classnames from 'classnames'; import SideNavigation from 'component/sideNavigation'; @@ -21,7 +22,6 @@ type Props = { isUpgradeAvailable: boolean, authPage: boolean, filePage: boolean, - homePage: boolean, noHeader: boolean, noFooter: boolean, noSideNavigation: boolean, @@ -56,16 +56,20 @@ function Page(props: Props) { const { location: { pathname }, } = useHistory(); - const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', true); + const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false); const isMediumScreen = useIsMediumScreen(); const isMobile = useIsMobile(); let isOnFilePage = false; try { - const url = pathname.slice(1).replace(/:/g, '#'); - const { isChannel } = parseURI(url); - if (!isChannel) { + if (pathname.includes(`/$/${PAGES.LIVESTREAM}`)) { isOnFilePage = true; + } else { + const url = pathname.slice(1).replace(/:/g, '#'); + const { isChannel } = parseURI(url); + if (!isChannel) { + isOnFilePage = true; + } } } catch (e) {} diff --git a/ui/component/publishAdditionalOptions/view.jsx b/ui/component/publishAdditionalOptions/view.jsx index b4ae97105..c37f7d41a 100644 --- a/ui/component/publishAdditionalOptions/view.jsx +++ b/ui/component/publishAdditionalOptions/view.jsx @@ -156,7 +156,7 @@ function PublishAdditionalOptions(props: Props) { type="select" name="content_language" value={language} - onChange={event => updatePublishForm({ language: event.target.value })} + onChange={(event) => updatePublishForm({ language: event.target.value })} > {Object.entries(SUPPORTED_LANGUAGES).map(([langkey, langName]) => ( // $FlowFixMe @@ -176,12 +176,12 @@ function PublishAdditionalOptions(props: Props) { licenseUrl: newLicenseUrl, }) } - handleLicenseDescriptionChange={event => + handleLicenseDescriptionChange={(event) => updatePublishForm({ otherLicenseDescription: event.target.value, }) } - handleLicenseUrlChange={event => updatePublishForm({ licenseUrl: event.target.value })} + handleLicenseUrlChange={(event) => updatePublishForm({ licenseUrl: event.target.value })} /> </div> </div> diff --git a/ui/component/publishFile/view.jsx b/ui/component/publishFile/view.jsx index 1b55b999f..47f1bc667 100644 --- a/ui/component/publishFile/view.jsx +++ b/ui/component/publishFile/view.jsx @@ -346,7 +346,8 @@ function PublishFile(props: Props) { subtitle={isStillEditing && __('You are currently editing your upload.')} actions={ <React.Fragment> - <PublishName /> + <PublishName uri={uri} /> + <FormField type="text" name="content_title" @@ -358,12 +359,16 @@ function PublishFile(props: Props) { /> {isPublishFile && ( <FileSelector - label={__('File')} + label={__('Video file')} disabled={disabled} currentPath={currentFile} onFileChosen={handleFileChange} + // https://stackoverflow.com/questions/19107685/safari-input-type-file-accept-video-ignores-mp4-files + accept="video/mp4,video/x-m4v,video/*" + placeholder={__('Select video file to upload')} /> )} + {isPublishFile && getMessage()} {isPublishPost && ( <PostEditor @@ -375,7 +380,7 @@ function PublishFile(props: Props) { setCurrentFileType={setCurrentFileType} /> )} - {isPublishFile && getMessage()} + {/* @if TARGET='app' */} {isPublishFile && ( <FormField diff --git a/ui/component/publishForm/index.js b/ui/component/publishForm/index.js index af8d06050..a55b15687 100644 --- a/ui/component/publishForm/index.js +++ b/ui/component/publishForm/index.js @@ -12,6 +12,7 @@ import { doPrepareEdit, doCheckPublishNameAvailability, SETTINGS, + selectMyChannelClaims, } from 'lbry-redux'; import { doPublishDesktop } from 'redux/actions/publish'; import { selectUnclaimedRewardValue } from 'redux/selectors/rewards'; @@ -35,6 +36,7 @@ const select = (state) => ({ modal: selectModal(state), enablePublishPreview: makeSelectClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW)(state), activeChannelClaim: selectActiveChannelClaim(state), + myChannels: selectMyChannelClaims(state), incognito: selectIncognito(state), }); diff --git a/ui/component/publishForm/view.jsx b/ui/component/publishForm/view.jsx index 1bd0041a6..042c19e7a 100644 --- a/ui/component/publishForm/view.jsx +++ b/ui/component/publishForm/view.jsx @@ -415,6 +415,7 @@ function PublishForm(props: Props) { <Button key={String(modeName)} icon={modeName} + iconSize={18} label={__(MODE_TO_I18N_STR[String(modeName)] || '---')} button="alt" onClick={() => { diff --git a/ui/component/publishName/name-help-text.jsx b/ui/component/publishName/name-help-text.jsx index 8abf29b14..c51a8aeb9 100644 --- a/ui/component/publishName/name-help-text.jsx +++ b/ui/component/publishName/name-help-text.jsx @@ -13,7 +13,6 @@ type Props = { function NameHelpText(props: Props) { const { uri, myClaimForUri, onEditMyClaim, isStillEditing } = props; - let nameHelpText; if (isStillEditing) { diff --git a/ui/component/recommendedContent/view.jsx b/ui/component/recommendedContent/view.jsx index 54e089a6c..ca749b920 100644 --- a/ui/component/recommendedContent/view.jsx +++ b/ui/component/recommendedContent/view.jsx @@ -1,4 +1,5 @@ // @flow +import { SEARCH_OPTIONS } from 'constants/search'; import { SHOW_ADS, SIMPLE_SITE } from 'config'; import React from 'react'; import ClaimList from 'component/claimList'; @@ -32,7 +33,13 @@ export default function RecommendedContent(props: Props) { if (stringifiedClaim) { const jsonClaim = JSON.parse(stringifiedClaim); if (jsonClaim && jsonClaim.value && jsonClaim.claim_id) { - const options: Options = { size: 20, related_to: jsonClaim.claim_id, isBackgroundSearch: true }; + const options: Options = { + size: 20, + related_to: jsonClaim.claim_id, + isBackgroundSearch: true, + [SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_FILES, + [SEARCH_OPTIONS.MEDIA_VIDEO]: true, + }; if (jsonClaim && !mature) { options['nsfw'] = false; } diff --git a/ui/component/repostCreate/view.jsx b/ui/component/repostCreate/view.jsx index dfda5ae04..914db4229 100644 --- a/ui/component/repostCreate/view.jsx +++ b/ui/component/repostCreate/view.jsx @@ -20,20 +20,20 @@ import Spinner from 'component/spinner'; type Props = { doToast: ({ message: string }) => void, doClearRepostError: () => void, - doRepost: StreamRepostOptions => Promise<*>, + doRepost: (StreamRepostOptions) => Promise<*>, title: string, claim?: StreamClaim, enteredContentClaim?: StreamClaim, balance: number, channels: ?Array<ChannelClaim>, - doCheckPublishNameAvailability: string => Promise<*>, + doCheckPublishNameAvailability: (string) => Promise<*>, error: ?string, reposting: boolean, uri: string, name: string, contentUri: string, - setRepostUri: string => void, - setContentUri: string => void, + setRepostUri: (string) => void, + setContentUri: (string) => void, doCheckPendingClaims: () => void, redirectUri?: string, passedRepostAmount: number, @@ -88,7 +88,7 @@ function RepostCreate(props: Props) { const repostUrlName = `lbry://${!activeChannelClaim ? '' : `${activeChannelClaim.name}/`}`; const contentFirstRender = React.useRef(true); - const setAutoRepostBid = amount => { + const setAutoRepostBid = (amount) => { if (balance && balance > 0.02) { if (uri) { setRepostBid(0.01); @@ -113,7 +113,7 @@ function RepostCreate(props: Props) { const isLbryUrl = value.startsWith('lbry://') && value !== 'lbry://'; const error = ''; - const addLbryIfNot = term => { + const addLbryIfNot = (term) => { return term.startsWith('lbry://') ? term : `lbry://${term}`; }; if (wasCopiedFromWeb) { @@ -178,7 +178,7 @@ function RepostCreate(props: Props) { React.useEffect(() => { if (enteredRepostName && isNameValid(enteredRepostName, false)) { - doCheckPublishNameAvailability(enteredRepostName).then(r => setAvailable(r)); + doCheckPublishNameAvailability(enteredRepostName).then((r) => setAvailable(r)); } }, [enteredRepostName, doCheckPublishNameAvailability]); @@ -316,7 +316,7 @@ function RepostCreate(props: Props) { <div> {uri && ( <fieldset-section> - <ClaimPreview key={uri} uri={uri} actions={''} type={'inline'} showNullPlaceholder /> + <ClaimPreview key={uri} uri={uri} actions={''} showNullPlaceholder /> </fieldset-section> )} {!uri && name && ( @@ -327,7 +327,7 @@ function RepostCreate(props: Props) { name="content_url" value={enteredContent} error={contentError} - onChange={event => setEnteredContentUri(event.target.value)} + onChange={(event) => setEnteredContentUri(event.target.value)} placeholder={__('Enter a name or %domain% URL', { domain: SITE_URL })} /> </> @@ -359,7 +359,7 @@ function RepostCreate(props: Props) { type="text" name="repost_name" value={enteredRepostName} - onChange={event => setEnteredRepostName(event.target.value)} + onChange={(event) => setEnteredRepostName(event.target.value)} placeholder={__('MyFunName')} /> </fieldset-group> @@ -384,8 +384,8 @@ function RepostCreate(props: Props) { </> } disabled={!enteredRepostName || resolvingRepost} - onChange={event => setRepostBid(event.target.value)} - onWheel={e => e.stopPropagation()} + onChange={(event) => setRepostBid(event.target.value)} + onWheel={(e) => e.stopPropagation()} /> </React.Fragment> diff --git a/ui/component/router/view.jsx b/ui/component/router/view.jsx index 056127b7a..1634bcb7c 100644 --- a/ui/component/router/view.jsx +++ b/ui/component/router/view.jsx @@ -49,6 +49,7 @@ import BuyPage from 'page/buy'; import NotificationsPage from 'page/notifications'; import SignInWalletPasswordPage from 'page/signInWalletPassword'; import YoutubeSyncPage from 'page/youtubeSync'; +import LiveStreamPage from 'page/livestream'; import { LINKED_COMMENT_QUERY_PARAM } from 'constants/comment'; import { parseURI, isURIValid } from 'lbry-redux'; @@ -216,6 +217,7 @@ function AppRouter(props: Props) { <Route path={`/`} exact component={HomePage} /> <Route path={`/$/${PAGES.DISCOVER}`} exact component={DiscoverPage} /> + <Route path={`/$/${PAGES.WILD_WEST}`} exact component={DiscoverPage} /> {/* $FlowFixMe */} {dynamicRoutes.map((dynamicRouteProps: RowDataItem) => ( <Route @@ -283,6 +285,9 @@ function AppRouter(props: Props) { <Route path={`/$/${PAGES.EMBED}/:claimName`} exact component={EmbedWrapperPage} /> <Route path={`/$/${PAGES.EMBED}/:claimName/:claimId`} exact component={EmbedWrapperPage} /> + + <Route path={`/$/${PAGES.LIVESTREAM}`} component={LiveStreamPage} /> + {/* Below need to go at the end to make sure we don't match any of our pages first */} <Route path="/:claimName" exact component={ShowPage} /> <Route path="/:claimName/:streamName" exact component={ShowPage} /> diff --git a/ui/component/searchOptions/view.jsx b/ui/component/searchOptions/view.jsx index 31e1f2053..f90dbe320 100644 --- a/ui/component/searchOptions/view.jsx +++ b/ui/component/searchOptions/view.jsx @@ -33,33 +33,34 @@ const SearchOptions = (props: Props) => { /> {expanded && ( <Form className="search__options"> - <fieldset> - <legend className="search__legend">{__('Search For')}</legend> - {[ - { - option: SEARCH_OPTIONS.INCLUDE_FILES, - label: __('Files'), - }, - { - option: SEARCH_OPTIONS.INCLUDE_CHANNELS, - label: __('Channels'), - }, - { - option: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS, - label: __('Everything'), - }, - ].map(({ option, label }) => ( - <FormField - key={option} - name={option} - type="radio" - blockWrap={false} - label={label} - checked={options[SEARCH_OPTIONS.CLAIM_TYPE] === option} - onChange={() => setSearchOption(SEARCH_OPTIONS.CLAIM_TYPE, option)} - /> - ))} - </fieldset> + {false && ( + <fieldset> + {[ + { + option: SEARCH_OPTIONS.INCLUDE_FILES, + label: __('Files'), + }, + { + option: SEARCH_OPTIONS.INCLUDE_CHANNELS, + label: __('Channels'), + }, + { + option: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS, + label: __('Everything'), + }, + ].map(({ option, label }) => ( + <FormField + key={option} + name={option} + type="radio" + blockWrap={false} + label={label} + checked={options[SEARCH_OPTIONS.CLAIM_TYPE] === option} + onChange={() => setSearchOption(SEARCH_OPTIONS.CLAIM_TYPE, option)} + /> + ))} + </fieldset> + )} <fieldset disabled={isFilteringByChannel}> <legend className="search__legend">{__('Type')}</legend> @@ -70,7 +71,7 @@ const SearchOptions = (props: Props) => { }, { option: SEARCH_OPTIONS.MEDIA_AUDIO, - label: __('Audio'), + label: __('Music'), }, { option: SEARCH_OPTIONS.MEDIA_IMAGE, @@ -98,22 +99,24 @@ const SearchOptions = (props: Props) => { ))} </fieldset> - <fieldset> - <legend className="search__legend">{__('Other Options')}</legend> - <FormField - type="select" - name="result-count" - value={resultCount} - onChange={(e) => setSearchOption(SEARCH_OPTIONS.RESULT_COUNT, e.target.value)} - blockWrap={false} - label={__('Returned Results')} - > - <option value={10}>10</option> - <option value={30}>30</option> - <option value={50}>50</option> - <option value={100}>100</option> - </FormField> - </fieldset> + {false && ( + <fieldset> + <legend className="search__legend">{__('Other Options')}</legend> + <FormField + type="select" + name="result-count" + value={resultCount} + onChange={(e) => setSearchOption(SEARCH_OPTIONS.RESULT_COUNT, e.target.value)} + blockWrap={false} + label={__('Returned Results')} + > + <option value={10}>10</option> + <option value={30}>30</option> + <option value={50}>50</option> + <option value={100}>100</option> + </FormField> + </fieldset> + )} </Form> )} </div> diff --git a/ui/component/selectThumbnail/view.jsx b/ui/component/selectThumbnail/view.jsx index 2293d5e31..be44a3707 100644 --- a/ui/component/selectThumbnail/view.jsx +++ b/ui/component/selectThumbnail/view.jsx @@ -99,7 +99,7 @@ class SelectThumbnail extends React.PureComponent<Props, State> { style={{ display: 'none' }} src={thumbnailSrc} alt={__('Thumbnail Preview')} - onError={e => { + onError={(e) => { this.setState({ thumbnailError: true, }); @@ -131,9 +131,9 @@ class SelectThumbnail extends React.PureComponent<Props, State> { <FileSelector currentPath={thumbnailPath} label={__('Thumbnail')} - placeholder={__('Choose a thumbnail')} + placeholder={__('Thumbnails that entice a viewer to watch a video work best')} accept={accept} - onFileChosen={file => openModal(MODALS.CONFIRM_THUMBNAIL_UPLOAD, { file })} + onFileChosen={(file) => openModal(MODALS.CONFIRM_THUMBNAIL_UPLOAD, { file })} /> )} {status === THUMBNAIL_STATUSES.COMPLETE && thumbnail && ( diff --git a/ui/component/sideNavigation/view.jsx b/ui/component/sideNavigation/view.jsx index 8e9e5b5ab..7822ef72d 100644 --- a/ui/component/sideNavigation/view.jsx +++ b/ui/component/sideNavigation/view.jsx @@ -51,6 +51,7 @@ type Props = { type SideNavLink = { title: string, link?: string, + route?: string, onClick?: () => any, icon: string, extra?: Node, @@ -60,7 +61,6 @@ type SideNavLink = { function SideNavigation(props: Props) { const { subscriptions, - followedTags, doSignOut, email, purchaseSuccess, @@ -72,6 +72,7 @@ function SideNavigation(props: Props) { unseenCount, homepageData, user, + followedTags, } = props; const { EXTRA_SIDEBAR_LINKS } = homepageData; @@ -211,7 +212,7 @@ function SideNavigation(props: Props) { }); } - const notificationsEnabled = user && user.experimental_ui; + const notificationsEnabled = SIMPLE_SITE || (user && user.experimental_ui); const isAuthenticated = Boolean(email); // SIDE LINKS: FOLLOWING, HOME, [FULL,] [EXTRA] let SIDE_LINKS: Array<SideNavLink> = []; @@ -291,8 +292,13 @@ function SideNavigation(props: Props) { <li className="navigation-link"> <Button label={__('FAQ')} href="https://odysee.com/@OdyseeHelp:b" /> </li> + <li className="navigation-link"> - <Button label={__('Support')} href="https://lbry.com/support" /> + <Button label={__('Community Guidelines')} href="https://odysee.com/@OdyseeHelp:b/Community-Guidelines:c" /> + </li> + + <li className="navigation-link"> + <Button label={__('Support --[used in footer; general help/support]--')} href="https://lbry.com/support" /> </li> <li className="navigation-link"> <Button label={__('Terms')} href="https://lbry.com/termsofservice" /> @@ -325,7 +331,7 @@ function SideNavigation(props: Props) { // $FlowFixMe const { hideForUnauth, ...passedProps } = linkProps; return !email && linkProps.hideForUnauth && IS_WEB ? null : ( - <li key={linkProps.link}> + <li key={linkProps.route || linkProps.link}> <Button {...passedProps} label={__(linkProps.title)} diff --git a/ui/component/subscribeButton/index.js b/ui/component/subscribeButton/index.js index b44b8584b..2460858eb 100644 --- a/ui/component/subscribeButton/index.js +++ b/ui/component/subscribeButton/index.js @@ -7,7 +7,6 @@ import { } from 'redux/selectors/subscriptions'; import { makeSelectPermanentUrlForUri } from 'lbry-redux'; import { doToast } from 'redux/actions/notifications'; -import { selectUser } from 'redux/selectors/user'; import SubscribeButton from './view'; const select = (state, props) => ({ @@ -15,7 +14,6 @@ const select = (state, props) => ({ firstRunCompleted: selectFirstRunCompleted(state), permanentUrl: makeSelectPermanentUrlForUri(props.uri)(state), notificationsDisabled: makeSelectNotificationsDisabled(props.uri)(state), - user: selectUser(state), }); export default connect(select, { diff --git a/ui/component/subscribeButton/view.jsx b/ui/component/subscribeButton/view.jsx index 0bc24a580..1bb20b617 100644 --- a/ui/component/subscribeButton/view.jsx +++ b/ui/component/subscribeButton/view.jsx @@ -15,13 +15,12 @@ type SubscriptionArgs = { type Props = { permanentUrl: ?string, isSubscribed: boolean, - doChannelSubscribe: SubscriptionArgs => void, - doChannelUnsubscribe: SubscriptionArgs => void, + doChannelSubscribe: (SubscriptionArgs) => void, + doChannelUnsubscribe: (SubscriptionArgs) => void, showSnackBarOnSubscribe: boolean, doToast: ({ message: string }) => void, shrinkOnMobile: boolean, notificationsDisabled: boolean, - user: ?User, }; export default function SubscribeButton(props: Props) { @@ -34,14 +33,12 @@ export default function SubscribeButton(props: Props) { doToast, shrinkOnMobile = false, notificationsDisabled, - user, } = props; const buttonRef = useRef(); const isMobile = useIsMobile(); let isHovering = useHover(buttonRef); isHovering = isMobile ? true : isHovering; - const uiNotificationsEnabled = user && user.experimental_ui; const { channelName } = parseURI(permanentUrl); const claimName = '@' + channelName; @@ -66,7 +63,7 @@ export default function SubscribeButton(props: Props) { requiresAuth={IS_WEB} label={label} title={titlePrefix} - onClick={e => { + onClick={(e) => { e.stopPropagation(); subscriptionHandler({ @@ -80,7 +77,7 @@ export default function SubscribeButton(props: Props) { } }} /> - {isSubscribed && uiNotificationsEnabled && ( + {isSubscribed && ( <Button button="alt" icon={notificationsDisabled ? ICONS.BELL : ICONS.BELL_ON} diff --git a/ui/component/syncPassword/view.jsx b/ui/component/syncPassword/view.jsx index 8e6622ce6..1ac9143b5 100644 --- a/ui/component/syncPassword/view.jsx +++ b/ui/component/syncPassword/view.jsx @@ -53,7 +53,7 @@ function SyncPassword(props: Props) { error={passwordError && __('Wrong password for %email%', { email })} label={__('Password for %email%', { email })} value={password} - onChange={e => setPassword(e.target.value)} + onChange={(e) => setPassword(e.target.value)} /> <FormField name="remember-password" @@ -75,7 +75,7 @@ function SyncPassword(props: Props) { <I18nMessage tokens={{ help: <Button button="link" label={__('help guide')} href="https://lbry.com/faq/account-sync" />, - email: <Button button="link" label={'help@lbry.com'} href="mailto:help@lbry.com" />, + email: <Button button="link" label={'help@odysee.com'} href="mailto:help@odysee.com" />, }} > If you are having issues, checkout our %help% or email us at %email%. diff --git a/ui/component/userChannelFollowIntro/view.jsx b/ui/component/userChannelFollowIntro/view.jsx index c1555403b..21e3e4ffc 100644 --- a/ui/component/userChannelFollowIntro/view.jsx +++ b/ui/component/userChannelFollowIntro/view.jsx @@ -11,24 +11,23 @@ import { AUTO_FOLLOW_CHANNELS, SIMPLE_SITE } from 'config'; type Props = { subscribedChannels: Array<Subscription>, onContinue: () => void, - onBack: () => void, channelSubscribe: (sub: Subscription) => void, homepageData: any, }; const channelsToSubscribe = AUTO_FOLLOW_CHANNELS.trim() .split(' ') - .filter(x => x !== ''); + .filter((x) => x !== ''); function UserChannelFollowIntro(props: Props) { - const { subscribedChannels, channelSubscribe, onContinue, onBack, homepageData } = props; + const { subscribedChannels, channelSubscribe, onContinue, homepageData } = props; const { PRIMARY_CONTENT_CHANNEL_IDS } = homepageData; const followingCount = (subscribedChannels && subscribedChannels.length) || 0; // subscribe to lbry useEffect(() => { if (channelsToSubscribe && channelsToSubscribe.length) { - channelsToSubscribe.forEach(c => + channelsToSubscribe.forEach((c) => channelSubscribe({ channelName: parseURI(c).claimName, uri: c, @@ -41,25 +40,25 @@ function UserChannelFollowIntro(props: Props) { <Card title={__('Find channels to follow')} subtitle={__( - 'LBRY works better if you find and follow a couple creators you like. You can also block channels you never want to see.' + 'Odysee works better if you find and follow a couple creators you like. You can also block channels you never want to see.' )} actions={ <React.Fragment> - <div className="section__actions--between"> - <Button button="secondary" onClick={onBack} label={__('Back')} /> - <Button - button={subscribedChannels.length < 1 ? 'alt' : 'primary'} - onClick={onContinue} - label={subscribedChannels.length < 1 ? __('Skip') : __('Continue')} - /> - </div> <div className="section__body"> <ClaimListDiscover - defaultOrderBy={CS.ORDER_BY_TOP} + hideFilters + meta={ + <Button + button={subscribedChannels.length < 1 ? 'alt' : 'primary'} + onClick={onContinue} + label={subscribedChannels.length < 1 ? __('Skip') : __('Continue')} + /> + } + defaultOrderBy={CS.ORDER_BY_TRENDING} defaultFreshness={CS.FRESH_ALL} - claimType="channel" - claimIds={SIMPLE_SITE ? undefined : PRIMARY_CONTENT_CHANNEL_IDS} - defaultTags={followingCount > 3 ? CS.TAGS_FOLLOWED : undefined} + claimIds={SIMPLE_SITE ? PRIMARY_CONTENT_CHANNEL_IDS : undefined} + claimType={CS.CLAIM_CHANNEL} + maxPages={3} /> {followingCount > 0 && ( <Nag diff --git a/ui/component/userEmailNew/view.jsx b/ui/component/userEmailNew/view.jsx index 916f89723..bec650323 100644 --- a/ui/component/userEmailNew/view.jsx +++ b/ui/component/userEmailNew/view.jsx @@ -100,7 +100,7 @@ function UserEmailNew(props: Props) { <Card title={__('Join %SITE_NAME%', { SITE_NAME })} // @if TARGET='app' - subtitle={__('An account with lbry.tv allows you to earn rewards and backup your data.')} + subtitle={__('An account with %domain% allows you to earn rewards and backup your data.', { domain: DOMAIN })} // @endif actions={ <div className={classnames({ 'card--disabled': DOMAIN === 'lbry.tv' })}> diff --git a/ui/component/userEmailVerify/view.jsx b/ui/component/userEmailVerify/view.jsx index 2b570c385..c9ee83d6e 100644 --- a/ui/component/userEmailVerify/view.jsx +++ b/ui/component/userEmailVerify/view.jsx @@ -8,10 +8,10 @@ const THIRTY_SECONDS_IN_MS = 30000; type Props = { email: string, isReturningUser: boolean, - resendVerificationEmail: string => void, + resendVerificationEmail: (string) => void, resendingEmail: boolean, checkEmailVerified: () => void, - toast: string => void, + toast: (string) => void, user: { has_verified_email: boolean, }, @@ -102,7 +102,7 @@ class UserEmailVerify extends React.PureComponent<Props, State> { <p className="help--card-actions"> <I18nMessage tokens={{ - help_link: <Button button="link" href="mailto:help@lbry.com" label="help@lbry.com" />, + help_link: <Button button="link" href="mailto:help@odysee.com" label="help@odysee.com" />, chat_link: <Button button="link" href="https://chat.lbry.com" label={__('chat')} />, }} > diff --git a/ui/component/userPhoneVerify/view.jsx b/ui/component/userPhoneVerify/view.jsx index 3211390dd..9b9a787b4 100644 --- a/ui/component/userPhoneVerify/view.jsx +++ b/ui/component/userPhoneVerify/view.jsx @@ -6,7 +6,7 @@ import I18nMessage from 'component/i18nMessage'; import Card from 'component/common/card'; type Props = { - verifyUserPhone: string => void, + verifyUserPhone: (string) => void, resetPhone: () => void, phoneErrorMessage: string, phone: string, @@ -61,7 +61,7 @@ class UserPhoneVerify extends React.PureComponent<Props, State> { name="code" placeholder="1234" value={this.state.code} - onChange={event => { + onChange={(event) => { this.handleCodeChanged(event); }} label={__('Verification Code')} @@ -72,7 +72,7 @@ class UserPhoneVerify extends React.PureComponent<Props, State> { <p className="help"> <I18nMessage tokens={{ - help_link: <Button button="link" href="mailto:help@lbry.com" label="help@lbry.com" />, + help_link: <Button button="link" href="mailto:help@odysee.com" label="help@odysee.com" />, chat_link: <Button button="link" href="https://chat.lbry.com" label={__('chat')} />, }} > diff --git a/ui/component/userSignUp/view.jsx b/ui/component/userSignUp/view.jsx index 11ddbcaeb..1b95f0df2 100644 --- a/ui/component/userSignUp/view.jsx +++ b/ui/component/userSignUp/view.jsx @@ -1,5 +1,4 @@ // @flow -import * as PAGES from 'constants/pages'; import React from 'react'; import classnames from 'classnames'; import { useHistory } from 'react-router'; @@ -7,7 +6,6 @@ import UserEmailNew from 'component/userEmailNew'; import UserEmailVerify from 'component/userEmailVerify'; import UserFirstChannel from 'component/userFirstChannel'; import UserChannelFollowIntro from 'component/userChannelFollowIntro'; -import UserTagFollowIntro from 'component/userTagFollowIntro'; import YoutubeSync from 'page/youtubeSync'; import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view'; import { YOUTUBE_STATUSES } from 'lbryinc'; @@ -42,7 +40,6 @@ type Props = { creatingChannel: boolean, setClientSetting: (string, boolean, ?boolean) => void, followingAcknowledged: boolean, - tagsAcknowledged: boolean, rewardsAcknowledged: boolean, interestedInYoutubeSync: boolean, doToggleInterestedInYoutubeSync: () => void, @@ -67,7 +64,6 @@ function UserSignUp(props: Props) { fetchingChannels, creatingChannel, followingAcknowledged, - tagsAcknowledged, rewardsAcknowledged, setClientSetting, interestedInYoutubeSync, @@ -118,8 +114,7 @@ function UserSignUp(props: Props) { interestedInYoutubeSync); const showYoutubeTransfer = hasVerifiedEmail && hasYoutubeChannels && !isYoutubeTransferComplete; const showFollowIntro = step === 'channels' || (hasVerifiedEmail && !followingAcknowledged); - const showTagsIntro = step === 'tags' || (hasVerifiedEmail && !tagsAcknowledged); - const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !showFollowIntro && !showTagsIntro && !rewardsAcknowledged; + const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !showFollowIntro && !rewardsAcknowledged; const isCurrentlyFetchingSomething = fetchingChannels || claimingReward || syncingWallet || creatingChannel; const isWaitingForSomethingToFinish = // If the user has claimed the email award, we need to wait until the balance updates sometime in the future @@ -206,22 +201,6 @@ function UserSignUp(props: Props) { }} /> ), - showTagsIntro && ( - <UserTagFollowIntro - onContinue={() => { - let url = `/$/${PAGES.AUTH}?reset_scroll=1&${STEP_PARAM}=channels`; - if (redirect) { - url += `&${REDIRECT_PARAM}=${redirect}`; - } - if (shouldRedirectImmediately) { - url += `&${REDIRECT_IMMEDIATELY_PARAM}=true`; - } - - replace(url); - setSettingAndSync(SETTINGS.TAGS_ACKNOWLEDGED, true); - }} - /> - ), showYoutubeTransfer && ( <div> <YoutubeTransferStatus /> <Confetti recycle={false} style={{ position: 'fixed' }} /> diff --git a/ui/component/userVerify/view.jsx b/ui/component/userVerify/view.jsx index e010507ea..7e5a5378a 100644 --- a/ui/component/userVerify/view.jsx +++ b/ui/component/userVerify/view.jsx @@ -12,7 +12,7 @@ import LbcSymbol from 'component/common/lbc-symbol'; type Props = { errorMessage: ?string, isPending: boolean, - verifyUserIdentity: string => void, + verifyUserIdentity: (string) => void, verifyPhone: () => void, fetchUser: () => void, skipLink?: string, @@ -60,7 +60,7 @@ class UserVerify extends React.PureComponent<Props> { SITE_NAME, }} > - Verified accounts are eligible to earn LBRY Credits for views, watching and reposting content, sharing + Verified accounts are eligible to earn LBRY Credits for views, watching and reposting videos, sharing invite links etc. Verifying also helps us keep the %SITE_NAME% community safe too! %Refresh% or %Skip%. </I18nMessage> </p> @@ -73,9 +73,7 @@ class UserVerify extends React.PureComponent<Props> { <Card icon={ICONS.PHONE} title={__('Verify phone number')} - subtitle={__( - 'You will receive an SMS text message confirming your phone number is valid. Does not work for Canada and possibly other regions.' - )} + subtitle={__('You will receive an SMS text message confirming your phone number is valid.')} actions={ <Fragment> <Button diff --git a/ui/component/viewers/videoViewer/internal/videojs.jsx b/ui/component/viewers/videoViewer/internal/videojs.jsx index a3834ea43..7fe27bc19 100644 --- a/ui/component/viewers/videoViewer/internal/videojs.jsx +++ b/ui/component/viewers/videoViewer/internal/videojs.jsx @@ -51,14 +51,14 @@ type Props = { toggleVideoTheaterMode: () => void, }; -type VideoJSOptions = { - controls: boolean, - preload: string, - playbackRates: Array<number>, - responsive: boolean, - poster?: string, - muted?: boolean, -}; +// type VideoJSOptions = { +// controls: boolean, +// preload: string, +// playbackRates: Array<number>, +// responsive: boolean, +// poster: ?string, +// muted: ?boolean, +// }; const videoPlaybackRates = [0.25, 0.5, 0.75, 1, 1.1, 1.25, 1.5, 1.75, 2]; @@ -67,7 +67,7 @@ const IS_IOS = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream; -const VIDEO_JS_OPTIONS: VideoJSOptions = { +const VIDEO_JS_OPTIONS = { preload: 'auto', playbackRates: videoPlaybackRates, responsive: true, @@ -172,9 +172,7 @@ properties for this component should be kept to ONLY those that if changed shoul */ export default React.memo<Props>(function VideoJs(props: Props) { const { autoplay, startMuted, source, sourceType, poster, isAudio, onPlayerReady, toggleVideoTheaterMode } = props; - const [reload, setReload] = useState('initial'); - const playerRef = useRef(); const containerRef = useRef(); const videoJsOptions = { diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index 75a2ffda0..8d3278350 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -73,6 +73,8 @@ function VideoViewer(props: Props) { const claimId = claim && claim.claim_id; const isAudio = contentType.includes('audio'); const forcePlayer = FORCE_CONTENT_TYPE_PLAYER.includes(contentType); + const previousUri = usePrevious(uri); + const embedded = useContext(EmbedContext); const [isPlaying, setIsPlaying] = useState(false); const [showAutoplayCountdown, setShowAutoplayCountdown] = useState(false); const [isEndededEmbed, setIsEndededEmbed] = useState(false); @@ -82,9 +84,6 @@ function VideoViewer(props: Props) { breaks because some browsers (e.g. Firefox) block autoplay but leave the player.play Promise pending */ const [isLoading, setIsLoading] = useState(false); - const previousUri = usePrevious(uri); - const embedded = useContext(EmbedContext); - // force everything to recent when URI changes, can cause weird corner cases otherwise (e.g. navigate while autoplay is true) useEffect(() => { if (uri && previousUri && uri !== previousUri) { diff --git a/ui/component/webUploadList/view.jsx b/ui/component/webUploadList/view.jsx index d0eb92dbc..c87c37ed0 100644 --- a/ui/component/webUploadList/view.jsx +++ b/ui/component/webUploadList/view.jsx @@ -21,7 +21,9 @@ export default function WebUploadList(props: Props) { !!uploadCount && ( <Card title={__('Currently uploading')} - subtitle={uploadCount > 1 ? __('You files are currently uploading.') : __('Your file is currently uploading.')} + subtitle={ + uploadCount > 1 ? __('You videos are currently uploading.') : __('Your video is currently uploading.') + } body={ <section> {/* $FlowFixMe */} diff --git a/ui/component/youtubeTransferStatus/view.jsx b/ui/component/youtubeTransferStatus/view.jsx index 2b22331ae..9beb96a18 100644 --- a/ui/component/youtubeTransferStatus/view.jsx +++ b/ui/component/youtubeTransferStatus/view.jsx @@ -119,7 +119,7 @@ export default function YoutubeTransferStatus(props: Props) { <I18nMessage tokens={{ here: <Button button="link" href="https://lbry.com/faq/youtube" label={__('here')} /> }} > - Email help@lbry.com if you think there has been a mistake. Make sure your channel qualifies %here%. + Email help@odysee.com if you think there has been a mistake. Make sure your channel qualifies %here%. </I18nMessage> )} </span> diff --git a/ui/constants/comment.js b/ui/constants/comment.js index 92e8c44c7..c1f553844 100644 --- a/ui/constants/comment.js +++ b/ui/constants/comment.js @@ -3,3 +3,22 @@ export const LINKED_COMMENT_QUERY_PARAM = 'lc'; export const SORT_COMMENTS_NEW = 'new'; export const SORT_COMMENTS_BEST = 'best'; export const SORT_COMMENTS_CONTROVERSIAL = 'controversial'; + +export const BANNED_LIVESTREAM_WORDS = [ + 'n1gga', + 'f4ggot', + 'faggot', + 'nigga', + 'nigger', + 'F4G', + 'fag', + 'n1gger', + 'faget', + 'niggah', + 'n1ggah', + 'jew', + 'j3w', + 'goy', + 'goyim', + 'fagot', +]; diff --git a/ui/constants/form-field.js b/ui/constants/form-field.js index 2b44de86b..0f5f3789d 100644 --- a/ui/constants/form-field.js +++ b/ui/constants/form-field.js @@ -1,3 +1,4 @@ export const FF_MAX_CHARS_DEFAULT = 2000; export const FF_MAX_CHARS_IN_COMMENT = 2000; +export const FF_MAX_CHARS_IN_LIVESTREAM_COMMENT = 300; export const FF_MAX_CHARS_IN_DESCRIPTION = 5000; diff --git a/ui/constants/pages.js b/ui/constants/pages.js index 20c951986..c15483c0b 100644 --- a/ui/constants/pages.js +++ b/ui/constants/pages.js @@ -61,3 +61,4 @@ exports.CHANNEL_NEW = 'channel/new'; exports.NOTIFICATIONS = 'notifications'; exports.YOUTUBE_SYNC = 'youtube'; exports.LIVESTREAM = 'livestream'; +exports.GENERAL = 'general'; diff --git a/ui/modal/modalPublish/view.jsx b/ui/modal/modalPublish/view.jsx index 6f821a94d..3bb9d10b9 100644 --- a/ui/modal/modalPublish/view.jsx +++ b/ui/modal/modalPublish/view.jsx @@ -40,7 +40,7 @@ class ModalPublishSuccess extends React.PureComponent<Props> { 'Your livestream is now pending. You will be able to start shortly at the streaming dashboard.' ); } else { - publishMessage = __('Your file is now pending on LBRY. It will take a few minutes to appear for other users.'); + publishMessage = __('Your video will appear on Odysee shortly.'); } function handleClose() { @@ -51,7 +51,7 @@ class ModalPublishSuccess extends React.PureComponent<Props> { return ( <Modal isOpen type="card" contentLabel={__(contentLabel)} onAborted={handleClose}> <Card - title={__('Success')} + title={livestream ? __('Livestream Created') : __('Upload Complete')} subtitle={publishMessage} body={ <React.Fragment> diff --git a/ui/modal/modalRemoveFile/view.jsx b/ui/modal/modalRemoveFile/view.jsx index 329e7821f..474c534c0 100644 --- a/ui/modal/modalRemoveFile/view.jsx +++ b/ui/modal/modalRemoveFile/view.jsx @@ -52,10 +52,8 @@ function ModalRemoveFile(props: Props) { <FormField name="claim_abandon" label={ - <I18nMessage - tokens={{ lbc: <LbcSymbol prefix={__('reclaim %amount%', { amount: claim.amount })} /> }} - > - Abandon on blockchain (%lbc%) + <I18nMessage tokens={{ lbc: <LbcSymbol postfix={claim.amount} /> }}> + Abandon on blockchain (reclaim %lbc%) </I18nMessage> } type="checkbox" diff --git a/ui/modal/modalTransactionFailed/view.jsx b/ui/modal/modalTransactionFailed/view.jsx index b4f4e4dea..c10e19f3b 100644 --- a/ui/modal/modalTransactionFailed/view.jsx +++ b/ui/modal/modalTransactionFailed/view.jsx @@ -12,7 +12,7 @@ class ModalTransactionFailed extends React.PureComponent<Props> { return ( <Modal isOpen contentLabel={__('Transaction failed')} title={__('Transaction failed')} onConfirmed={closeModal}> - <p>{__('Sorry about that. Contact help@lbry.com if you continue to have issues.')}</p> + <p>{__('Sorry about that. Contact help@odysee.com if you continue to have issues.')}</p> </Modal> ); } diff --git a/ui/modal/modalYoutubeWelcome/view.jsx b/ui/modal/modalYoutubeWelcome/view.jsx index c8584952d..2548019db 100644 --- a/ui/modal/modalYoutubeWelcome/view.jsx +++ b/ui/modal/modalYoutubeWelcome/view.jsx @@ -1,4 +1,5 @@ // @flow +import { SIMPLE_SITE } from 'config'; import * as PAGES from 'constants/pages'; import React from 'react'; import { Modal } from 'modal/modal'; @@ -15,18 +16,27 @@ const YoutubeWelcome = (props: Props) => { <Modal isOpen type="card" onAborted={doHideModal}> <Confetti recycle={false} style={{ position: 'fixed' }} numberOfPieces={100} /> <Card - title={__("You're free!")} + title={!SIMPLE_SITE ? __("You're free!") : __('Welcome to Odysee')} subtitle={ - <React.Fragment> - <p> - {__("You've escaped the land of spying, censorship, and exploitation.")} - <span className="emoji"> 💩</span> - </p> - <p> - {__('Welcome to the land of content freedom.')} - <span className="emoji"> 🌈</span> - </p> - </React.Fragment> + !SIMPLE_SITE ? ( + <React.Fragment> + <p> + {__("You've escaped the land of spying, censorship, and exploitation.")} + <span className="emoji"> 💩</span> + </p> + <p> + {__('Welcome to the land of content freedom.')} + <span className="emoji"> 🌈</span> + </p> + </React.Fragment> + ) : ( + <React.Fragment> + <p> + {__('You make the party extra special!')} + <span className="emoji"> 💖</span> + </p> + </React.Fragment> + ) } actions={ <div className="card__actions"> diff --git a/ui/page/adsTest/index.js b/ui/page/adsTest/index.js new file mode 100644 index 000000000..ffdfa5135 --- /dev/null +++ b/ui/page/adsTest/index.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux'; +import { makeSelectClaimForUri, doResolveUri } from 'lbry-redux'; +import AdsTestPage from './view'; + +export default connect( + (state) => ({ + claim: makeSelectClaimForUri('lbry://fullscreenrelease#7')(state), + }), + { + doResolveUri, + } +)(AdsTestPage); diff --git a/ui/page/adsTest/view.jsx b/ui/page/adsTest/view.jsx new file mode 100644 index 000000000..4893445c6 --- /dev/null +++ b/ui/page/adsTest/view.jsx @@ -0,0 +1,20 @@ +// @flow +// import React from 'react'; +// import FilePage from 'page/file'; + +type Props = { + doResolveUri: (string) => void, + claim: ?StreamClaim, +}; + +export default function AdsTestPage(props: Props) { + return null; + // const { doResolveUri, claim } = props; + // const hasClaim = claim !== undefined; + // React.useEffect(() => { + // if (!hasClaim) { + // doResolveUri('lbry://fullscreenrelease#7'); + // } + // }, [hasClaim, doResolveUri]); + // return <div>{hasClaim && <FilePage uri="lbry://fullscreenrelease#7" />}</div>; +} diff --git a/ui/page/buy/view.jsx b/ui/page/buy/view.jsx index 13340ba5a..b0f2a1c02 100644 --- a/ui/page/buy/view.jsx +++ b/ui/page/buy/view.jsx @@ -18,7 +18,7 @@ const MOONPAY_KEY = process.env.MOONPAY_SECRET_KEY; const COUNTRIES = Array.from( new Set( countryData.all - .map(country => country.name) + .map((country) => country.name) .sort((a, b) => { if (a > b) { return 1; @@ -39,7 +39,7 @@ type Props = { email: string, user: ?User, doGetNewAddress: () => void, - doUserSetCountry: string => void, + doUserSetCountry: (string) => void, }; export default function BuyPage(props: Props) { @@ -65,7 +65,7 @@ export default function BuyPage(props: Props) { React.useEffect(() => { if (MOONPAY_KEY && !url && receiveAddress) { - let url = `https://buy.moonpay.io?apiKey=pk_live_xNFffrN5NWKy6fu0ggbV8VQIwRieRzy&colorCode=%23257761¤cyCode=lbc&showWalletAddressForm=true&walletAddress=${receiveAddress}`; + let url = `https://buy.moonpay.io?apiKey=pk_live_xNFffrN5NWKy6fu0ggbV8VQIwRieRzy&colorCode=%23fa6165¤cyCode=lbc&showWalletAddressForm=true&walletAddress=${receiveAddress}`; if (email) { url += `&email=${encodeURIComponent(email)}`; } @@ -148,7 +148,7 @@ export default function BuyPage(props: Props) { 'Only some countries are eligible at this time. We are working to make this available to everyone.' )} value={country} - onChange={e => setCountry(e.target.value)} + onChange={(e) => setCountry(e.target.value)} > <option value="" disabled defaultValue> {__('Select your country')} diff --git a/ui/page/channels/view.jsx b/ui/page/channels/view.jsx index 4afd973d5..fbe1f4704 100644 --- a/ui/page/channels/view.jsx +++ b/ui/page/channels/view.jsx @@ -109,7 +109,7 @@ export default function ChannelsPage(props: Props) { subtitle={__("You haven't created a channel yet. All of your beautiful channels will be listed here!")} actions={ <div className="section__actions"> - <Button button="primary" label={__('New Channel')} navigate={`/$/${PAGES.CHANNEL_NEW}`} /> + <Button button="primary" label={__('Create Channel')} navigate={`/$/${PAGES.CHANNEL_NEW}`} /> </div> } /> diff --git a/ui/page/channelsFollowing/view.jsx b/ui/page/channelsFollowing/view.jsx index 9cdff0831..4dccab699 100644 --- a/ui/page/channelsFollowing/view.jsx +++ b/ui/page/channelsFollowing/view.jsx @@ -23,6 +23,7 @@ function ChannelsFollowingPage(props: Props) { ) : ( <Page noFooter fullWidthPage={tileLayout}> <ClaimListDiscover + hideAdvancedFilter tileLayout={tileLayout} headerLabel={ <span> @@ -31,7 +32,7 @@ function ChannelsFollowingPage(props: Props) { </span> } defaultOrderBy={ORDER_BY_NEW} - channelIds={subscribedChannels.map(sub => sub.uri.split('#')[1])} + channelIds={subscribedChannels.map((sub) => sub.uri.split('#')[1])} meta={ <Button icon={ICONS.SEARCH} diff --git a/ui/page/channelsFollowingDiscover/view.jsx b/ui/page/channelsFollowingDiscover/view.jsx index aa5875599..46a01b50c 100644 --- a/ui/page/channelsFollowingDiscover/view.jsx +++ b/ui/page/channelsFollowingDiscover/view.jsx @@ -1,13 +1,12 @@ // @flow -import * as ICONS from 'constants/icons'; -import * as PAGES from 'constants/pages'; +// import * as ICONS from 'constants/icons'; +// import * as PAGES from 'constants/pages'; +import * as CS from 'constants/claim_search'; import React from 'react'; import Page from 'component/page'; -import Button from 'component/button'; -import ClaimTilesDiscover from 'component/claimTilesDiscover'; +// import Button from 'component/button'; import ClaimListDiscover from 'component/claimListDiscover'; -import * as CS from 'constants/claim_search'; -import { toCapitalCase } from 'util/string'; +// import { toCapitalCase } from 'util/string'; import { SIMPLE_SITE } from 'config'; const MORE_CHANNELS_ANCHOR = 'MoreChannels'; @@ -19,89 +18,87 @@ type Props = { homepageData: any, }; -type ChannelsFollowingItem = { - title: string, - link?: string, - help?: any, - options?: {}, -}; - function ChannelsFollowingDiscover(props: Props) { - const { followedTags, subscribedChannels, blockedChannels, homepageData } = props; + const { + // followedTags, + // subscribedChannels, + // blockedChannels, + homepageData, + } = props; const { PRIMARY_CONTENT_CHANNEL_IDS } = homepageData; - let rowData: Array<ChannelsFollowingItem> = []; - const notChannels = subscribedChannels - .map(({ uri }) => uri) - .concat(blockedChannels) - .map(uri => uri.split('#')[1]); + // let rowData: Array<ChannelsFollowingItem> = []; + // const notChannels = subscribedChannels + // .map(({ uri }) => uri) + // .concat(blockedChannels) + // .map(uri => uri.split('#')[1]); - rowData.push({ - title: 'Top Channels Of All Time', - link: `/$/${PAGES.DISCOVER}?claim_type=channel&${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TOP}&${CS.FRESH_KEY}=${CS.FRESH_ALL}`, - options: { - pageSize: 12, - claimType: 'channel', - orderBy: ['effective_amount'], - }, - }); + // rowData.push({ + // title: 'Top Channels Of All Time', + // link: `/$/${PAGES.DISCOVER}?claim_type=channel&${CS.ORDER_BY_KEY}=${CS.ORDER_BY_TOP}&${CS.FRESH_KEY}=${CS.FRESH_ALL}`, + // options: { + // pageSize: 12, + // claimType: 'channel', + // orderBy: ['effective_amount'], + // }, + // }); - rowData.push({ - title: 'Latest From @lbrycast', - link: `/@lbrycast:4`, - options: { - orderBy: ['release_time'], - pageSize: 8, - channelIds: ['4c29f8b013adea4d5cca1861fb2161d5089613ea'], - }, - }); + // rowData.push({ + // title: 'Latest From @lbrycast', + // link: `/@lbrycast:4`, + // options: { + // orderBy: ['release_time'], + // pageSize: 8, + // channelIds: ['4c29f8b013adea4d5cca1861fb2161d5089613ea'], + // }, + // }); - rowData.push({ - title: 'Trending Channels', - link: `/$/${PAGES.DISCOVER}?claim_type=channel`, - options: { - pageSize: 8, - claimType: 'channel', - orderBy: ['trending_group', 'trending_mixed'], - }, - }); + // rowData.push({ + // title: 'Trending Channels', + // link: `/$/${PAGES.DISCOVER}?claim_type=channel`, + // options: { + // pageSize: 8, + // claimType: 'channel', + // orderBy: ['trending_group', 'trending_mixed'], + // }, + // }); - if (followedTags.length > 0 && followedTags.length < 5) { - const followedRows = followedTags.map((tag: Tag) => ({ - title: `Trending Channels for #${toCapitalCase(tag.name)}`, - link: `/$/${PAGES.DISCOVER}?t=${tag.name}&claim_type=channel`, - options: { - claimType: 'channel', - pageSize: 4, - tags: [tag.name], - }, - })); - rowData.push(...followedRows); - } + // if (followedTags.length > 0 && followedTags.length < 5) { + // const followedRows = followedTags.map((tag: Tag) => ({ + // title: `Trending Channels for #${toCapitalCase(tag.name)}`, + // link: `/$/${PAGES.DISCOVER}?t=${tag.name}&claim_type=channel`, + // options: { + // claimType: 'channel', + // pageSize: 4, + // tags: [tag.name], + // }, + // })); + // rowData.push(...followedRows); + // } - if (followedTags.length > 4) { - rowData.push({ - title: 'Trending For Your Tags', - link: `/$/${PAGES.TAGS_FOLLOWING}?claim_type=channel`, - options: { - claimType: 'channel', - tags: followedTags.map(tag => tag.name), - }, - }); - } + // if (followedTags.length > 4) { + // rowData.push({ + // title: 'Trending For Your Tags', + // link: `/$/${PAGES.TAGS_FOLLOWING}?claim_type=channel`, + // options: { + // claimType: 'channel', + // tags: followedTags.map(tag => tag.name), + // }, + // }); + // } - const rowDataWithGenericOptions = rowData.map(row => { - return { - ...row, - options: { - ...row.options, - notChannels, - }, - }; - }); + // const rowDataWithGenericOptions = rowData.map(row => { + // return { + // ...row, + // options: { + // ...row.options, + // notChannels, + // }, + // }; + // }); return ( <Page> - {rowDataWithGenericOptions.map(({ title, link, help, options = {} }) => ( + {/* {rowDataWithGenericOptions.map(({ title, link, help, options = {} }) => ( <div key={title} className="claim-grid__wrapper"> <h1 className="section__actions"> {link ? ( @@ -120,17 +117,17 @@ function ChannelsFollowingDiscover(props: Props) { <ClaimTilesDiscover {...options} /> </div> - ))} - <h1 id={MORE_CHANNELS_ANCHOR} className="claim-grid__title"> - {__('More Channels')} - </h1> - {/* odysee: claimIds = PRIMARY_CONTENT_CHANNEL_IDS if simplesite CLD */} + ))} */} + <ClaimListDiscover defaultOrderBy={CS.ORDER_BY_TRENDING} defaultFreshness={CS.FRESH_ALL} claimType={CS.CLAIM_CHANNEL} claimIds={SIMPLE_SITE ? PRIMARY_CONTENT_CHANNEL_IDS : undefined} scrollAnchor={MORE_CHANNELS_ANCHOR} + maxPages={3} + hideFilters + header={<h1 className="section__title">{__('Moon cheese is an acquired taste')}</h1>} /> </Page> ); diff --git a/ui/page/discover/view.jsx b/ui/page/discover/view.jsx index 19b144898..fe229c9be 100644 --- a/ui/page/discover/view.jsx +++ b/ui/page/discover/view.jsx @@ -1,6 +1,7 @@ // @flow import { SHOW_ADS, DOMAIN, SIMPLE_SITE } from 'config'; import * as ICONS from 'constants/icons'; +import * as CS from 'constants/claim_search'; import React, { useRef } from 'react'; import Page from 'component/page'; import ClaimListDiscover from 'component/claimListDiscover'; @@ -10,18 +11,18 @@ import { useIsMobile } from 'effects/use-screensize'; import analytics from 'analytics'; import HiddenNsfw from 'component/common/hidden-nsfw'; import Icon from 'component/common/icon'; -import * as CS from 'constants/claim_search'; import Ads from 'web/component/ads'; import LbcSymbol from 'component/common/lbc-symbol'; import I18nMessage from 'component/i18nMessage'; +import moment from 'moment'; type Props = { location: { search: string }, followedTags: Array<Tag>, repostedUri: string, repostedClaim: ?GenericClaim, - doToggleTagFollowDesktop: string => void, - doResolveUri: string => void, + doToggleTagFollowDesktop: (string) => void, + doResolveUri: (string) => void, isAuthenticated: boolean, dynamicRouteProps: RowDataItem, tileLayout: boolean, @@ -87,8 +88,8 @@ function DiscoverPage(props: Props) { } else { headerLabel = ( <span> - <Icon icon={(dynamicRouteProps && dynamicRouteProps.icon) || ICONS.DISCOVER} size={10} /> - {(dynamicRouteProps && dynamicRouteProps.title) || __('All Content')} + <Icon icon={(dynamicRouteProps && dynamicRouteProps.icon) || ICONS.WILD_WEST} size={10} /> + {(dynamicRouteProps && dynamicRouteProps.title) || __('Wild West')} </span> ); } @@ -96,9 +97,11 @@ function DiscoverPage(props: Props) { return ( <Page noFooter fullWidthPage={tileLayout}> <ClaimListDiscover - limitClaimsPerChannel={3} + hideAdvancedFilter + hideFilters={!dynamicRouteProps} header={repostedUri ? <span /> : undefined} tileLayout={repostedUri ? false : tileLayout} + defaultOrderBy={dynamicRouteProps ? undefined : CS.ORDER_BY_TRENDING} claimType={claimType ? [claimType] : undefined} headerLabel={headerLabel} tags={tags} @@ -107,9 +110,18 @@ function DiscoverPage(props: Props) { injectedItem={ SHOW_ADS && IS_WEB ? (SIMPLE_SITE ? false : !isAuthenticated && <Ads small type={'video'} />) : false } + // Assume wild west page if no dynamicRouteProps + // Not a very good solution, but just doing it for now + // until we are sure this page will stay around + releaseTime={!dynamicRouteProps && `>${Math.floor(moment().subtract(1, 'day').startOf('week').unix())}`} + feeAmount={!dynamicRouteProps && CS.FEE_AMOUNT_ANY} channelIds={ (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.channelIds) || undefined } + limitClaimsPerChannel={ + (dynamicRouteProps && dynamicRouteProps.options && dynamicRouteProps.options.limitClaimsPerChannel) || + undefined + } meta={ !dynamicRouteProps ? ( <a diff --git a/ui/page/file/index.js b/ui/page/file/index.js index cc9570d87..07e6511e9 100644 --- a/ui/page/file/index.js +++ b/ui/page/file/index.js @@ -8,6 +8,8 @@ import { makeSelectClaimIsNsfw, SETTINGS, makeSelectTagInClaimOrChannelForUri, + makeSelectClaimIsMine, + makeSelectClaimHasSource, } from 'lbry-redux'; import { makeSelectCostInfoForUri, doFetchCostInfoForUri } from 'lbryinc'; import { selectShowMatureContent, makeSelectClientSetting } from 'redux/selectors/settings'; @@ -32,14 +34,16 @@ const select = (state, props) => { renderMode: makeSelectFileRenderModeForUri(props.uri)(state), videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state), commentsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state), + claimIsMine: makeSelectClaimIsMine(props.uri)(state), + isLivestream: !makeSelectClaimHasSource(props.uri)(state), }; }; -const perform = dispatch => ({ - fetchFileInfo: uri => dispatch(doFetchFileInfo(uri)), - fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)), - setViewed: uri => dispatch(doSetContentHistoryItem(uri)), - setPrimaryUri: uri => dispatch(doSetPrimaryUri(uri)), +const perform = (dispatch) => ({ + fetchFileInfo: (uri) => dispatch(doFetchFileInfo(uri)), + fetchCostInfo: (uri) => dispatch(doFetchCostInfoForUri(uri)), + setViewed: (uri) => dispatch(doSetContentHistoryItem(uri)), + setPrimaryUri: (uri) => dispatch(doSetPrimaryUri(uri)), }); export default withRouter(connect(select, perform)(FilePage)); diff --git a/ui/page/file/view.jsx b/ui/page/file/view.jsx index f6dd8aecf..0241f54b9 100644 --- a/ui/page/file/view.jsx +++ b/ui/page/file/view.jsx @@ -1,4 +1,5 @@ // @flow +import * as PAGES from 'constants/pages'; import * as React from 'react'; import classnames from 'classnames'; import Page from 'component/page'; @@ -10,6 +11,9 @@ import FileRenderDownload from 'component/fileRenderDownload'; import RecommendedContent from 'component/recommendedContent'; import CommentsList from 'component/commentsList'; import PostViewer from 'component/postViewer'; +import { Redirect } from 'react-router'; +import Button from 'component/button'; +import I18nMessage from 'component/i18nMessage'; import Empty from 'component/common/empty'; export const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container'; @@ -27,7 +31,10 @@ type Props = { linkedComment: any, setPrimaryUri: (?string) => void, videoTheaterMode: boolean, + claim: ?Claim, + claimIsMine: boolean, commentsDisabled: boolean, + isLivestream: boolean, }; function FilePage(props: Props) { @@ -44,7 +51,10 @@ function FilePage(props: Props) { linkedComment, setPrimaryUri, videoTheaterMode, + + claimIsMine, commentsDisabled, + isLivestream, } = props; const cost = costInfo ? costInfo.cost : null; const hasFileInfo = fileInfo !== undefined; @@ -113,6 +123,10 @@ function FilePage(props: Props) { ); } + if (!claimIsMine && isLivestream) { + return <Redirect to={`/$/${PAGES.LIVESTREAM}`} />; + } + if (obscureNsfw && isMature) { return ( <Page> @@ -129,6 +143,18 @@ function FilePage(props: Props) { {!isMarkdown && ( <div className="file-page__secondary-content"> <div> + {claimIsMine && isLivestream && ( + <div className="livestream__creator-message"> + <h4>{__('Only visible to you')}</h4> + <I18nMessage> + People who view this link will be redirected to your livestream. Make sure to use this for sharing + so your title and thumbnail are displayed properly. + </I18nMessage> + <div className="section__actions"> + <Button button="primary" navigate={`/$/${PAGES.LIVESTREAM}`} label={__('View livestream')} /> + </div> + </div> + )} {RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />} {commentsDisabled && <Empty text={__('The creator of this content has disabled comments.')} />} {!commentsDisabled && <CommentsList uri={uri} linkedComment={linkedComment} />} diff --git a/ui/page/help/view.jsx b/ui/page/help/view.jsx index 9a7512dbf..140560ac0 100644 --- a/ui/page/help/view.jsx +++ b/ui/page/help/view.jsx @@ -1,4 +1,5 @@ // @flow +import { SITE_NAME } from 'config'; import * as ICONS from 'constants/icons'; import * as PAGES from 'constants/pages'; import * as React from 'react'; @@ -129,19 +130,13 @@ class HelpPage extends React.PureComponent<Props, State> { return ( <Page className="card-stack"> <Card - title={__('Read the FAQ')} - subtitle={__('Our FAQ answers many common questions.')} + title={__('Visit the %SITE_NAME% Help Hub', { SITE_NAME })} + subtitle={__('Our support posts answer many common questions.')} actions={ <div className="section__actions"> <Button - href="https://lbry.com/faq/lbry-basics" - label={__('Read the App Basics FAQ')} - icon={ICONS.HELP} - button="secondary" - /> - <Button - href="https://lbry.com/faq" - label={__('View all LBRY FAQs')} + href="https://odysee.com/@OdyseeHelp:b" + label={__('View %SITE_NAME% Help Hub', { SITE_NAME })} icon={ICONS.HELP} button="secondary" /> @@ -160,7 +155,7 @@ class HelpPage extends React.PureComponent<Props, State> { actions={ <div className="section__actions"> <Button button="secondary" label={__('Join Our Chat')} icon={ICONS.CHAT} href="https://chat.lbry.com" /> - <Button button="secondary" label={__('Email Us')} icon={ICONS.WEB} href="mailto:help@lbry.com" /> + <Button button="secondary" label={__('Email Us')} icon={ICONS.WEB} href="mailto:help@odysee.com" /> </div> } /> @@ -210,7 +205,6 @@ class HelpPage extends React.PureComponent<Props, State> { /> <WalletBackup /> - {/* @endif */} <Card title={__('About --[About section in Help Page]--')} @@ -295,6 +289,7 @@ class HelpPage extends React.PureComponent<Props, State> { </div> } /> + {/* @endif */} </Page> ); } diff --git a/ui/page/home/view.jsx b/ui/page/home/view.jsx index 7c37b8d76..69439db8b 100644 --- a/ui/page/home/view.jsx +++ b/ui/page/home/view.jsx @@ -79,9 +79,12 @@ function HomePage(props: Props) { </p> </div> )} + + <h1 className="home__meme">{__("Video stonks.")}</h1> + {rowData.map(({ title, route, link, icon, help, options = {} }, index) => ( <div key={title} className="claim-grid__wrapper"> - {title && ( + {index !== 0 && title && typeof title === 'string' && ( <h1 className="claim-grid__header"> <Button navigate={route || link} button="link"> {icon && <Icon className="claim-grid__header-icon" sectionIcon icon={icon} size={20} />} @@ -91,8 +94,8 @@ function HomePage(props: Props) { </h1> )} - <ClaimTilesDiscover {...options} /> - {link && ( + <ClaimTilesDiscover {...options} pin={route === `/$/${PAGES.GENERAL}`} /> + {(route || link) && ( <Button className="claim-grid__title--secondary" button="link" diff --git a/ui/page/rewards/view.jsx b/ui/page/rewards/view.jsx index a51be2ccf..8b4c163b7 100644 --- a/ui/page/rewards/view.jsx +++ b/ui/page/rewards/view.jsx @@ -78,8 +78,8 @@ class RewardsPage extends PureComponent<Props> { rewards_faq: <Button button="link" label={__('Rewards FAQ')} href="https://lbry.com/faq/support" />, }} > - Please review the %rewards_faq% for eligibility, and send us an email to help@lbry.com if you continue - to see this message. You can continue to use LBRY without this feature. + Please review the %rewards_faq% for eligibility, and send us an email to help@odysee.com if you + continue to see this message. You can continue to use LBRY without this feature. </I18nMessage> {`${__('Enjoy all the awesome free content in the meantime!')}`} </p> @@ -156,7 +156,7 @@ class RewardsPage extends PureComponent<Props> { 'card--disabled': isNotEligible, })} > - {rewards.map(reward => ( + {rewards.map((reward) => ( <RewardTile key={reward.claim_code} reward={reward} /> ))} {this.renderCustomRewardCode()} diff --git a/ui/page/search/index.js b/ui/page/search/index.js index d808e7a7f..b64386a45 100644 --- a/ui/page/search/index.js +++ b/ui/page/search/index.js @@ -14,17 +14,12 @@ import analytics from 'analytics'; import SearchPage from './view'; const select = (state, props) => { - const showMature = makeSelectClientSetting(SETTINGS.SHOW_MATURE)(state); const urlParams = new URLSearchParams(props.location.search); let urlQuery = urlParams.get('q') || null; if (urlQuery) { urlQuery = urlQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); } - - const query = makeSelectQueryWithOptions( - urlQuery, - showMature === false ? { nsfw: false, isBackgroundSearch: false } : { isBackgroundSearch: false } - )(state); + const query = makeSelectQueryWithOptions(urlQuery, { nsfw: false, isBackgroundSearch: false })(state); const uris = makeSelectSearchUris(query)(state); return { @@ -36,9 +31,9 @@ const select = (state, props) => { }; }; -const perform = dispatch => ({ +const perform = (dispatch) => ({ search: (query, options) => dispatch(doSearch(query, options)), - onFeedbackPositive: query => { + onFeedbackPositive: (query) => { analytics.apiSearchFeedback(query, 1); dispatch( doToast({ @@ -46,7 +41,7 @@ const perform = dispatch => ({ }) ); }, - onFeedbackNegative: query => { + onFeedbackNegative: (query) => { analytics.apiSearchFeedback(query, 0); dispatch( doToast({ diff --git a/ui/page/search/view.jsx b/ui/page/search/view.jsx index b884a08ba..7416cfa94 100644 --- a/ui/page/search/view.jsx +++ b/ui/page/search/view.jsx @@ -24,8 +24,8 @@ type Props = { isSearching: boolean, location: UrlLocation, uris: Array<string>, - onFeedbackNegative: string => void, - onFeedbackPositive: string => void, + onFeedbackNegative: (string) => void, + onFeedbackPositive: (string) => void, showNsfw: boolean, isAuthenticated: boolean, }; @@ -38,7 +38,7 @@ export default function SearchPage(props: Props) { onFeedbackNegative, location, isSearching, - showNsfw, + // showNsfw, isAuthenticated, searchOptions, } = props; @@ -47,12 +47,9 @@ export default function SearchPage(props: Props) { const urlQuery = urlParams.get('q') || ''; const additionalOptions: AdditionalOptions = { isBackgroundSearch: false }; - additionalOptions['nsfw'] = showNsfw; + additionalOptions['nsfw'] = false; - const modifiedUrlQuery = urlQuery - .trim() - .replace(/\s+/g, '') - .replace(/:/g, '#'); + const modifiedUrlQuery = urlQuery.trim().replace(/\s+/g, '').replace(/:/g, '#'); const uriFromQuery = `lbry://${modifiedUrlQuery}`; let streamName; @@ -72,7 +69,7 @@ export default function SearchPage(props: Props) { try { const dummyUrlForClaimId = `x#${urlQuery}`; ({ claimId } = parseURI(dummyUrlForClaimId)); - Lbry.claim_search({ claim_id: claimId }).then(res => { + Lbry.claim_search({ claim_id: claimId }).then((res) => { if (res.items && res.items.length) { const claim = res.items[0]; const url = formatLbryUrlForWeb(claim.canonical_url); @@ -105,21 +102,23 @@ export default function SearchPage(props: Props) { SHOW_ADS && IS_WEB ? (SIMPLE_SITE ? false : !isAuthenticated && <Ads small type={'video'} />) : false } headerAltControls={ - <> - <span>{__('Find what you were looking for?')}</span> - <Button - button="alt" - description={__('Yes')} - onClick={() => onFeedbackPositive(urlQuery)} - icon={ICONS.YES} - /> - <Button - button="alt" - description={__('No')} - onClick={() => onFeedbackNegative(urlQuery)} - icon={ICONS.NO} - /> - </> + !SIMPLE_SITE && ( + <> + <span>{__('Find what you were looking for?')}</span> + <Button + button="alt" + description={__('Yes')} + onClick={() => onFeedbackPositive(urlQuery)} + icon={ICONS.YES} + /> + <Button + button="alt" + description={__('No')} + onClick={() => onFeedbackNegative(urlQuery)} + icon={ICONS.NO} + /> + </> + ) } /> {isSearching && new Array(5).fill(1).map((x, i) => <ClaimPreview key={i} placeholder="loading" />)} diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index 3854fae9a..2b1ed27a5 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -1,6 +1,6 @@ // @flow import * as PAGES from 'constants/pages'; -import * as MODALS from 'constants/modal_types'; +// import * as MODALS from 'constants/modal_types'; import * as ICONS from 'constants/icons'; import * as React from 'react'; import { SETTINGS } from 'lbry-redux'; @@ -17,7 +17,7 @@ import classnames from 'classnames'; import { getPasswordFromCookie } from 'util/saved-passwords'; // $FlowFixMe import homepages from 'homepages'; -import { Lbryio } from 'lbryinc'; +// import { Lbryio } from 'lbryinc'; import Yrbl from 'component/yrbl'; type Price = { @@ -27,10 +27,10 @@ type Price = { type SetDaemonSettingArg = boolean | string | number; -type DarkModeTimes = { - from: { hour: string, min: string, formattedTime: string }, - to: { hour: string, min: string, formattedTime: string }, -}; +// type DarkModeTimes = { +// from: { hour: string, min: string, formattedTime: string }, +// to: { hour: string, min: string, formattedTime: string }, +// }; type OptionTimes = { fromTo: string, @@ -64,7 +64,7 @@ type Props = { floatingPlayer: boolean, hideReposts: ?boolean, clearPlayingUri: () => void, - darkModeTimes: DarkModeTimes, + // darkModeTimes: DarkModeTimes, setDarkTime: (string, {}) => void, openModal: (string) => void, language?: string, @@ -160,11 +160,11 @@ class SettingsPage extends React.PureComponent<Props, State> { const { daemonSettings, allowAnalytics, - showNsfw, + // showNsfw, isAuthenticated, currentTheme, themes, - automaticDarkModeEnabled, + // automaticDarkModeEnabled, autoplay, walletEncrypted, // autoDownload, @@ -172,16 +172,16 @@ class SettingsPage extends React.PureComponent<Props, State> { setClientSetting, toggle3PAnalytics, floatingPlayer, - hideReposts, + // hideReposts, clearPlayingUri, - darkModeTimes, + // darkModeTimes, clearCache, - openModal, + // openModal, } = this.props; const { storedPassword } = this.state; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; - const startHours = ['18', '19', '20', '21']; - const endHours = ['5', '6', '7', '8']; + // const startHours = ['18', '19', '20', '21']; + // const endHours = ['5', '6', '7', '8']; return ( <Page @@ -258,7 +258,7 @@ class SettingsPage extends React.PureComponent<Props, State> { label={__('Theme')} onChange={this.onThemeChange} value={currentTheme} - disabled={automaticDarkModeEnabled} + // disabled={automaticDarkModeEnabled} > {themes.map((theme) => ( <option key={theme} value={theme}> @@ -267,7 +267,7 @@ class SettingsPage extends React.PureComponent<Props, State> { ))} </FormField> </fieldset-section> - <fieldset-section> + {/* <fieldset-section> <FormField type="checkbox" name="automatic_dark_mode" @@ -305,7 +305,7 @@ class SettingsPage extends React.PureComponent<Props, State> { </FormField> </fieldset-group> )} - </fieldset-section> + </fieldset-section> */} </React.Fragment> } /> @@ -337,7 +337,7 @@ class SettingsPage extends React.PureComponent<Props, State> { )} /> - <FormField + {/* <FormField type="checkbox" name="hide_reposts" onChange={(e) => { @@ -351,7 +351,7 @@ class SettingsPage extends React.PureComponent<Props, State> { checked={hideReposts} label={__('Hide reposts')} helper={__('You will not see reposts by people you follow or receive email notifying about them.')} - /> + /> */} {/* <FormField type="checkbox" @@ -362,7 +362,7 @@ class SettingsPage extends React.PureComponent<Props, State> { helper={__('Anonymous content is published without a channel.')} /> */} - <FormField + {/* <FormField type="checkbox" name="show_nsfw" onChange={() => @@ -375,7 +375,7 @@ class SettingsPage extends React.PureComponent<Props, State> { helper={__( 'Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying mature content, you are affirming you are of legal age to view mature content in your country or jurisdiction. ' )} - /> + /> */} </React.Fragment> } /> diff --git a/ui/page/show/index.js b/ui/page/show/index.js index 888cab2bc..438043138 100644 --- a/ui/page/show/index.js +++ b/ui/page/show/index.js @@ -1,3 +1,4 @@ +import * as PAGES from 'constants/pages'; import { DOMAIN } from 'config'; import { connect } from 'react-redux'; import { PAGE_SIZE } from 'constants/claim'; @@ -11,7 +12,10 @@ import { makeSelectClaimIsMine, makeSelectClaimIsPending, makeSelectClaimIsStreamPlaceholder, + doClearPublish, + doPrepareEdit, } from 'lbry-redux'; +import { push } from 'connected-react-router'; import { makeSelectChannelInSubscriptions } from 'redux/selectors/subscriptions'; import { selectBlackListedOutpoints } from 'lbryinc'; import ShowPage from './view'; @@ -67,6 +71,11 @@ const select = (state, props) => { const perform = (dispatch) => ({ resolveUri: (uri) => dispatch(doResolveUri(uri)), + beginPublish: (name) => { + dispatch(doClearPublish()); + dispatch(doPrepareEdit({ name })); + dispatch(push(`/$/${PAGES.PUBLISH}`)); + }, }); export default connect(select, perform)(ShowPage); diff --git a/ui/page/show/view.jsx b/ui/page/show/view.jsx index 7039b0220..b959762e1 100644 --- a/ui/page/show/view.jsx +++ b/ui/page/show/view.jsx @@ -10,7 +10,9 @@ import Page from 'component/page'; import Button from 'component/button'; import Card from 'component/common/card'; import AbandonedChannelPreview from 'component/abandonedChannelPreview'; +import Yrbl from 'component/yrbl'; import { formatLbryUrlForWeb } from 'util/url'; +import { parseURI } from 'lbry-redux'; type Props = { isResolvingUri: boolean, @@ -27,6 +29,8 @@ type Props = { claimIsMine: boolean, claimIsPending: boolean, isLivestream: boolean, + claimIsMine: Boolean, + beginPublish: (string) => void, }; function ShowPage(props: Props) { @@ -41,6 +45,7 @@ function ShowPage(props: Props) { isSubscribed, claimIsPending, isLivestream, + beginPublish, } = props; const signingChannel = claim && claim.signing_channel; @@ -48,6 +53,7 @@ function ShowPage(props: Props) { const claimExists = claim !== null && claim !== undefined; const haventFetchedYet = claim === undefined; const isMine = claim && claim.is_my_output; + const { contentName } = parseURI(uri); useEffect(() => { // @if TARGET='web' @@ -84,11 +90,20 @@ function ShowPage(props: Props) { <Page> {(claim === undefined || isResolvingUri) && ( <div className="main--empty"> - <Spinner /> + <Spinner delayed /> </div> )} {!isResolvingUri && !isSubscribed && ( - <span className="empty">{__("There's nothing available at this location.")}</span> + <div className="main--empty"> + <Yrbl + title={__('No Content Found')} + subtitle={ + <div className="section__actions"> + <Button button="primary" label={__('Publish Something')} onClick={() => beginPublish(contentName)} /> + </div> + } + /> + </div> )} {!isResolvingUri && isSubscribed && claim === null && <AbandonedChannelPreview uri={uri} type={'large'} />} </Page> diff --git a/ui/page/top/view.jsx b/ui/page/top/view.jsx index 6dee23f6d..ef8bf9fef 100644 --- a/ui/page/top/view.jsx +++ b/ui/page/top/view.jsx @@ -5,14 +5,14 @@ import Page from 'component/page'; import ClaimListDiscover from 'component/claimListDiscover'; import ClaimEffectiveAmount from 'component/claimEffectiveAmount'; import SearchTopClaim from 'component/searchTopClaim'; -import { ORDER_BY_TOP, FRESH_ALL } from 'constants/claim_search'; +import * as CS from 'constants/claim_search'; import Button from 'component/button'; import I18nMessage from 'component/i18nMessage'; import * as PAGES from 'constants/pages'; type Props = { name: string, - beginPublish: string => void, + beginPublish: (string) => void, }; function TopPage(props: Props) { @@ -25,8 +25,9 @@ function TopPage(props: Props) { <SearchTopClaim query={name} hideLink setChannelActive={setChannelActive} /> <ClaimListDiscover name={channelActive ? `@${queryName}` : queryName} - defaultFreshness={FRESH_ALL} - defaultOrderBy={ORDER_BY_TOP} + defaultFreshness={CS.FRESH_ALL} + defaultOrderBy={CS.ORDER_BY_TOP} + streamType={CS.CONTENT_ALL} meta={ <div className="search__top-links"> <I18nMessage @@ -46,7 +47,7 @@ function TopPage(props: Props) { </div> } includeSupportAction - renderProperties={claim => ( + renderProperties={(claim) => ( <span className="claim-preview__custom-properties"> {claim.meta.is_controlling && <span className="help--inline">{__('Currently winning')}</span>} <ClaimEffectiveAmount uri={claim.repost_url || claim.canonical_url} /> diff --git a/ui/redux/actions/comments.js b/ui/redux/actions/comments.js index e5737c8c2..4197d17f4 100644 --- a/ui/redux/actions/comments.js +++ b/ui/redux/actions/comments.js @@ -2,6 +2,7 @@ import * as ACTIONS from 'constants/action_types'; import * as REACTION_TYPES from 'constants/reactions'; import { Lbry, parseURI, buildURI, selectClaimsByUri, selectMyChannelClaims } from 'lbry-redux'; +// import { BANNED_LIVESTREAM_WORDS } from 'constants/comment'; import { doToast, doSeeNotifications } from 'redux/actions/notifications'; import { makeSelectCommentIdsForUri, @@ -216,6 +217,27 @@ export function doCommentCreate( type: ACTIONS.COMMENT_CREATE_STARTED, }); + // if (livestream) { + // const strippedCommentText = comment.trim().toLowerCase().replace(/\s/g, ''); + // for (var i = 0; i < BANNED_LIVESTREAM_WORDS.length; i++) { + // const bannedWord = BANNED_LIVESTREAM_WORDS[i]; + // if (strippedCommentText.includes(bannedWord)) { + // dispatch({ + // type: ACTIONS.COMMENT_CREATE_FAILED, + // }); + // + // dispatch( + // doToast({ + // message: 'Unable to create comment.', + // isError: true, + // }) + // ); + // + // return; + // } + // } + // } + if (parent_id) { const notification = makeSelectNotificationForCommentId(parent_id)(state); if (notification && !notification.is_seen) { diff --git a/ui/redux/reducers/search.js b/ui/redux/reducers/search.js index 8d9f7d435..018dbc571 100644 --- a/ui/redux/reducers/search.js +++ b/ui/redux/reducers/search.js @@ -6,13 +6,13 @@ import { SEARCH_OPTIONS } from 'constants/search'; const defaultState: SearchState = { // $FlowFixMe options: { - [SEARCH_OPTIONS.RESULT_COUNT]: 30, - [SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS, - [SEARCH_OPTIONS.MEDIA_AUDIO]: true, + [SEARCH_OPTIONS.RESULT_COUNT]: 50, + [SEARCH_OPTIONS.CLAIM_TYPE]: 'file,channel', + [SEARCH_OPTIONS.MEDIA_AUDIO]: false, [SEARCH_OPTIONS.MEDIA_VIDEO]: true, - [SEARCH_OPTIONS.MEDIA_TEXT]: true, - [SEARCH_OPTIONS.MEDIA_IMAGE]: true, - [SEARCH_OPTIONS.MEDIA_APPLICATION]: true, + [SEARCH_OPTIONS.MEDIA_TEXT]: false, + [SEARCH_OPTIONS.MEDIA_IMAGE]: false, + [SEARCH_OPTIONS.MEDIA_APPLICATION]: false, }, urisByQuery: {}, searching: false, diff --git a/ui/redux/reducers/settings.js b/ui/redux/reducers/settings.js index da5823b4f..5452b40a5 100644 --- a/ui/redux/reducers/settings.js +++ b/ui/redux/reducers/settings.js @@ -8,7 +8,7 @@ import { UNSYNCED_SETTINGS } from 'config'; const { CLIENT_SYNC_KEYS } = SHARED_PREFERENCES; const settingsToIgnore = (UNSYNCED_SETTINGS && UNSYNCED_SETTINGS.trim().split(' ')) || []; const clientSyncKeys = settingsToIgnore.length - ? CLIENT_SYNC_KEYS.filter(k => !settingsToIgnore.includes(k)) + ? CLIENT_SYNC_KEYS.filter((k) => !settingsToIgnore.includes(k)) : CLIENT_SYNC_KEYS; const reducers = {}; @@ -69,7 +69,7 @@ const defaultState = { [SETTINGS.AUTOPLAY_NEXT]: true, [SETTINGS.FLOATING_PLAYER]: true, [SETTINGS.AUTO_DOWNLOAD]: true, - [SETTINGS.HIDE_REPOSTS]: false, + [SETTINGS.HIDE_REPOSTS]: true, // OS [SETTINGS.AUTO_LAUNCH]: true, @@ -88,12 +88,12 @@ reducers[ACTIONS.REHYDRATE] = (state, action) => { return Object.assign({}, state, { clientSettings }); }; -reducers[ACTIONS.FINDING_FFMPEG_STARTED] = state => +reducers[ACTIONS.FINDING_FFMPEG_STARTED] = (state) => Object.assign({}, state, { findingFFmpeg: true, }); -reducers[ACTIONS.FINDING_FFMPEG_COMPLETED] = state => +reducers[ACTIONS.FINDING_FFMPEG_COMPLETED] = (state) => Object.assign({}, state, { findingFFmpeg: false, }); @@ -119,7 +119,7 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => { }); }; -reducers[ACTIONS.UPDATE_IS_NIGHT] = state => { +reducers[ACTIONS.UPDATE_IS_NIGHT] = (state) => { const { from, to } = state.clientSettings[SETTINGS.DARK_MODE_TIMES]; const momentNow = moment(); const startNightMoment = moment(from.formattedTime, 'HH:mm'); @@ -154,7 +154,7 @@ reducers[LBRY_REDUX_ACTIONS.SHARED_PREFERENCE_SET] = (state, action) => { }); }; -reducers[ACTIONS.SYNC_CLIENT_SETTINGS] = state => { +reducers[ACTIONS.SYNC_CLIENT_SETTINGS] = (state) => { const { clientSettings } = state; const sharedPreferences = Object.assign({}, state.sharedPreferences); const selectedClientSettings = getSubsetFromKeysArray(clientSettings, clientSyncKeys); diff --git a/ui/scss/component/_ads.scss b/ui/scss/component/_ads.scss index e206a1da8..dea783836 100644 --- a/ui/scss/component/_ads.scss +++ b/ui/scss/component/_ads.scss @@ -83,3 +83,51 @@ .ads__claim-text--small { font-size: var(--font-small); } + +.ads__video-nudge, +.ads__video-notify { + position: absolute; + z-index: 3; +} + +.ads__video-nudge { + right: 0; + left: 0; + bottom: 0; + background-color: var(--color-primary); + color: var(--color-white); + font-weight: bold; + padding: var(--spacing-xs); +} + +.ads__video-notify { + display: flex; + align-items: center; + right: 0; + top: 0; + background-color: black; + border-bottom-left-radius: var(--border-radius); + color: var(--color-white); + font-size: var(--font-small); + padding: var(--spacing-xs); +} + +.ads__video-link.button--secondary { + font-size: var(--font-small); + padding: var(--spacing-xs); + height: 1.5rem; +} + +.ads__video-close { + margin-left: var(--spacing-s); + border-radius: var(--border-radius); + + .icon { + stroke: var(--color-white); + + &:hover { + stroke: var(--color-black); + background-color: var(--color-white); + } + } +} diff --git a/ui/scss/component/_button.scss b/ui/scss/component/_button.scss index 84a1b435e..5c47d3643 100644 --- a/ui/scss/component/_button.scss +++ b/ui/scss/component/_button.scss @@ -34,7 +34,14 @@ .button--primary { background-color: var(--color-button-primary-bg); - color: var(--color-button-primary-text); + + .button__label { + color: var(--color-button-primary-text); + } + + .icon { + stroke: var(--color-button-primary-text); + } &:hover { color: var(--color-button-primary-hover-text); @@ -54,7 +61,14 @@ .button--secondary { background-color: var(--color-button-secondary-bg); border: 1px solid var(--color-button-secondary-border); - color: var(--color-button-secondary-text); + + .button__label { + color: var(--color-button-secondary-text); + } + + .icon { + stroke: var(--color-button-secondary-text); + } &:hover { background-color: var(--color-button-secondary-bg-hover); @@ -223,6 +237,238 @@ } } +.button--fire { + color: var(--color-fire); + position: relative; + + path { + stroke: var(--color-fire-outside); + } +} + +.button__fire-particle { + position: absolute; + top: 60%; + left: 20%; + width: 2px; + height: 2px; + background-color: #ef5a00; + border-radius: 50%; + filter: drop-shadow(0 0 10px #d43322); + animation-iteration-count: 2; + animation-fill-mode: both; +} + +.button__fire-glow { + width: 1px; + height: 1px; + left: var(--spacing-s); + bottom: var(--spacing-m); + position: absolute; + box-shadow: 4px 0px 10px 10px var(--color-glow); + animation: glowDecay 2.5s ease-out; + opacity: 0; +} + +.button__fire-particle1 { + @extend .button__fire-particle; + right: 10%; + top: 40%; + animation: particleUp 1.5s ease-out 0; + animation-iteration-count: 2; + animation-fill-mode: both; +} +.button__fire-particle2 { + @extend .button__fire-particle; + animation: particleUp2 2s ease-out 0; + animation-iteration-count: 2; + animation-fill-mode: both; +} +.button__fire-particle3 { + @extend .button__fire-particle; + animation: particleUp3 2.2s ease-out 0; + animation-iteration-count: 2; + animation-fill-mode: both; +} +.button__fire-particle4 { + @extend .button__fire-particle1; + animation-delay: 0.5s; +} +.button__fire-particle5 { + @extend .button__fire-particle2; + animation-delay: 0.75s; +} +.button__fire-particle6 { + @extend .button__fire-particle3; + animation-delay: 0.25s; +} + +@keyframes glowDecay { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes particleUp { + 0% { + opacity: 0; + left: 0; + } + 20% { + opacity: 1; + right: 10%; + } + + 50% { + right: 20%; + } + + 50% { + left: 10%; + } + 80% { + opacity: 1; + right: 40%; + } + 100% { + opacity: 0; + top: -50%; + transform: scale(0.5); + } +} + +@keyframes particleUp2 { + 0% { + opacity: 0; + right: 0; + } + 20% { + opacity: 1; + left: 10%; + } + + 50% { + left: 20%; + } + + 50% { + right: 10%; + } + 80% { + opacity: 1; + left: 40%; + } + 100% { + opacity: 0; + top: -50%; + transform: scale(0.5); + } +} + +@keyframes particleUp3 { + 0% { + opacity: 0; + left: 30%; + } + 20% { + opacity: 1; + left: 60%; + } + + 40% { + left: 50%; + } + + 80% { + opacity: 1; + right: 80%; + } + 100% { + opacity: 0; + top: -50%; + transform: scale(0.5); + } +} + +.button--slime { + color: var(--color-slime); +} + +.button__slime-drop { + position: absolute; + top: 60%; + left: 15%; + width: 5px; + height: 5px; + background-color: #81c554; + border-radius: 50%; + filter: drop-shadow(0 0 10px #d43322); + animation-iteration-count: 2; + animation-fill-mode: both; +} + +.button__slime-drop1 { + @extend .button__slime-drop; + top: 40%; + animation: dropDown 1.5s ease-out 0; + animation-iteration-count: 1; + animation-fill-mode: both; +} + +.button__slime-drop2 { + @extend .button__slime-drop; + left: 35%; + top: 40%; + animation: dropDown2 1.5s ease-out 0; + animation-iteration-count: 1; + animation-fill-mode: both; +} + +.button__slime-stain { + width: 1px; + height: 1px; + left: var(--spacing-s); + bottom: var(--spacing-m); + position: absolute; + box-shadow: 4px 0px 10px 10px var(--color-slime); + animation: glowDecay 2.5s ease-out; + opacity: 0; +} + +@keyframes dropDown { + 0% { + opacity: 1; + top: 50%; + } + 70% { + opacity: 1; + } + 100% { + opacity: 0; + top: 80%; + transform: scale(0.5, 4); + } +} + +@keyframes dropDown2 { + 0% { + opacity: 1; + top: 50%; + } + 60% { + opacity: 1; + } + 100% { + opacity: 0; + top: 80%; + transform: scale(0.5, 6); + } +} + .button--disabled { opacity: 0.5; } @@ -303,8 +549,8 @@ svg + .button__label { } .button-toggle--active { - color: var(--color-primary); - background-color: var(--color-primary-alt); + color: var(--color-button-toggle-text); + background-color: var(--color-button-toggle-bg); svg { opacity: 1; @@ -313,7 +559,7 @@ svg + .button__label { &:hover { cursor: default; text-decoration: none; - background-color: var(--color-primary-alt); + background-color: var(--color-button-toggle-bg-hover); } } @@ -348,6 +594,12 @@ svg + .button__label { border-top-left-radius: 0; border-bottom-left-radius: 0; } + + .button--file-action { + &:first-child { + margin-right: var(--spacing-s); + } + } } .button-toggle-group-action { diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss index 55b8027f4..1c43cac05 100644 --- a/ui/scss/component/_card.scss +++ b/ui/scss/component/_card.scss @@ -17,7 +17,7 @@ .card--section { position: relative; - padding: var(--spacing-l); + padding: var(--spacing-m); } .card--reward-total { @@ -82,7 +82,7 @@ .card__title-section { @extend .section__flex; - padding: var(--spacing-m) var(--spacing-l); + padding: var(--spacing-s) var(--spacing-m); @media (max-width: $breakpoint-small) { padding: 0; @@ -90,7 +90,7 @@ } .card__title-section--body-list { - padding: var(--spacing-m); + padding: var(--spacing-s); @media (max-width: $breakpoint-small) { padding: 0; @@ -98,7 +98,11 @@ } .card__title-section--small { - padding: var(--spacing-s) var(--spacing-m); + padding: 0; + + @media (min-width: $breakpoint-small) { + padding: var(--spacing-s) var(--spacing-m); + } } .card__actions--inline { @@ -175,7 +179,7 @@ .card__title { display: block; align-items: center; - font-size: var(--font-title); + font-size: var(--font-large); font-weight: var(--font-weight-light); & > *:not(:last-child) { @@ -200,8 +204,7 @@ .card__title-actions { align-self: flex-start; - padding: var(--spacing-m); - padding-right: var(--spacing-l); + padding: var(--spacing-s); @media (max-width: $breakpoint-small) { padding: 0; @@ -258,7 +261,7 @@ } .card__body { - padding: var(--spacing-l); + padding: var(--spacing-m); &:not(.card__body--no-title) { padding-top: 0; @@ -275,9 +278,9 @@ } .card__main-actions { - padding: var(--spacing-l); + padding: var(--spacing-m); padding-bottom: 0; - margin-bottom: var(--spacing-l); + margin-bottom: var(--spacing-m); border-top: 1px solid var(--color-border); &:only-child { @@ -286,7 +289,7 @@ } .card__body-actions { - padding: var(--spacing-l); + padding: var(--spacing-m); @media (max-width: $breakpoint-small) { padding: var(--spacing-s); @@ -339,3 +342,9 @@ margin-right: var(--spacing-m); } } + +.card__bottom-actions { + display: flex; + justify-content: space-between; + align-items: center; +} diff --git a/ui/scss/component/_channel.scss b/ui/scss/component/_channel.scss index e9f0eb223..26ab9b14c 100644 --- a/ui/scss/component/_channel.scss +++ b/ui/scss/component/_channel.scss @@ -103,6 +103,7 @@ $metadata-z-index: 1; .channel-thumbnail__custom { width: 100%; object-fit: cover; + font-size: 1px; // To hide the alt text on firefox; } .channel-thumbnail__default { @@ -274,7 +275,8 @@ $metadata-z-index: 1; &[data-selected] { background: transparent; - .channel__list-item { + .channel__list-item, + .channel-staked__wrapper { background-color: var(--color-card-background-highlighted); } } @@ -308,6 +310,7 @@ $metadata-z-index: 1; background-color: var(--color-card-background); padding: var(--spacing-s); border-bottom: 1px solid var(--color-border); + overflow: hidden; .channel-thumbnail { height: 2rem; @@ -356,16 +359,12 @@ $metadata-z-index: 1; .channel-staked__tooltip { display: flex; align-items: center; + line-height: 1rem; } .channel-staked__tooltip-text { margin-left: var(--spacing-xs); font-size: var(--font-xsmall); - - .icon--LBC { - opacity: 0.7; - margin-top: -2px; - } } .channel-staked__wrapper { diff --git a/ui/scss/component/_claim-list.scss b/ui/scss/component/_claim-list.scss index f6cb92cbb..1d0a71e74 100644 --- a/ui/scss/component/_claim-list.scss +++ b/ui/scss/component/_claim-list.scss @@ -30,9 +30,11 @@ transform: translateY(-130%); font-size: var(--font-xsmall); color: var(--color-text-subtitle); + overflow: visible; .icon { margin-right: var(--spacing-xs); + stroke: var(--color-text-subtitle); } @media (max-width: $breakpoint-small) { @@ -179,6 +181,20 @@ @include handleChannelGif(5rem); } } + + .claim-preview__text { + height: 7.5rem; + } + + @media (max-width: $breakpoint-small) { + .channel-thumbnail { + @include handleChannelGif(6rem); + } + + .claim-preview__text { + height: 3.5rem; + } + } } .claim-preview--small { @@ -202,12 +218,15 @@ .claim-preview--inline { .channel-thumbnail { - @include handleChannelGif(var(--channel-thumbnail-width--small)); + @include handleChannelGif(3rem); + + @media (min-width: $breakpoint-small) { + @include handleChannelGif(var(--channel-thumbnail-width--small)); + } } .claim-preview__actions { align-self: flex-end; - margin-top: 0; margin-bottom: auto; justify-content: flex-end; width: auto; @@ -218,11 +237,16 @@ flex-direction: row; justify-content: space-between; flex-wrap: wrap; + align-items: center; } @media (max-width: $breakpoint-xsmall) { .claim-preview__actions { - align-self: flex-start; + .claim-preview__primary-actions { + .button { + margin-top: 0; + } + } } } } @@ -255,10 +279,6 @@ display: flex; flex-direction: column; flex: 1; - - @media (max-width: $breakpoint-small) { - margin-bottom: var(--spacing-s); - } } .claim-preview-info { @@ -276,7 +296,6 @@ display: flex; flex-direction: column; justify-content: space-between; - margin-top: auto; width: 100%; @media (min-width: $breakpoint-small) { @@ -286,7 +305,14 @@ .claim-preview__primary-actions { @extend .section__actions; - margin-top: 0; + margin-right: 0; + margin-top: var(--spacing-s); + + &:first-child { + .button { + margin-top: var(--spacing-s); + } + } } .claim-preview__actions--header { @@ -386,6 +412,16 @@ font-size: var(--font-large); } +.claim-grid__title--first { + text-align: center; + width: 100%; + margin-bottom: var(--spacing-l); + + .no-evil { + font-size: var(--font-heading); + } +} + .claim-grid__title--secondary { margin-left: auto; } diff --git a/ui/scss/component/_comments.scss b/ui/scss/component/_comments.scss index b45f8b2b0..e398f9eb4 100644 --- a/ui/scss/component/_comments.scss +++ b/ui/scss/component/_comments.scss @@ -33,6 +33,10 @@ $thumbnailWidthSmall: 1rem; position: relative; } +.comment__create--bottom { + padding-bottom: 0; +} + .comment { width: 100%; display: flex; @@ -61,6 +65,12 @@ $thumbnailWidthSmall: 1rem; margin-left: 0; } } + + .channel-staked__indicator { + @media (max-width: $breakpoint-small) { + margin-left: 0.1rem; + } + } } } @@ -286,6 +296,10 @@ $thumbnailWidthSmall: 1rem; padding-bottom: var(--spacing-xs); font-size: var(--font-small); border-bottom: 1px solid var(--color-border); + + &:not(:last-child) { + margin-bottom: var(--spacing-xs); + } } .comment__menu-help { diff --git a/ui/scss/component/_file-properties.scss b/ui/scss/component/_file-properties.scss index e394d76fe..fbef50618 100644 --- a/ui/scss/component/_file-properties.scss +++ b/ui/scss/component/_file-properties.scss @@ -25,6 +25,7 @@ font-size: var(--font-xsmall); line-height: 1.2; margin-left: 0; + margin-top: auto; position: relative; .tag { diff --git a/ui/scss/component/_file-render.scss b/ui/scss/component/_file-render.scss index 6a881cd00..6f1d24462 100644 --- a/ui/scss/component/_file-render.scss +++ b/ui/scss/component/_file-render.scss @@ -5,11 +5,11 @@ .card + .file-render, .card + .file-page__video-container, .card + .content__cover { - margin-top: var(--spacing-l); + margin-top: var(--spacing-m); } .card + .file-render { - margin-top: var(--spacing-l); + margin-top: var(--spacing-m); } .file-page__md { @@ -203,13 +203,28 @@ } .file-viewer__overlay-logo { - color: var(--color-white); - font-weight: bold; + height: 3.5rem; + width: 12rem; + display: flex; + align-items: center; - .icon { - height: 30px; - stroke-width: 5px; + &:hover { + filter: drop-shadow(1px 2px 10px var(--color-gray-3)); } + + @media (max-width: $breakpoint-small) { + margin-right: var(--spacing-m); + width: 2.5rem; + + .button__label { + display: none; + } + } +} + +.file-viewer__overlay-logo--videoend { + height: 3.5rem; + width: 12rem; } .file-viewer--is-playing:not(:hover) .file-viewer__embedded-header { @@ -219,11 +234,15 @@ .file-viewer__embedded-header { position: absolute; display: flex; + align-items: center; justify-content: space-between; width: 100%; top: 0; opacity: 1; z-index: 2; + height: 4rem; + padding-left: var(--spacing-m); + padding-right: var(--spacing-s); font-size: var(--font-large); overflow-x: hidden; overflow-y: hidden; @@ -233,7 +252,6 @@ border-top-right-radius: var(--border-radius); .button { - padding: var(--spacing-s); color: var(--color-white); z-index: 2; diff --git a/ui/scss/component/_footer.scss b/ui/scss/component/_footer.scss index 3b3deab6d..85b443584 100644 --- a/ui/scss/component/_footer.scss +++ b/ui/scss/component/_footer.scss @@ -1,7 +1,8 @@ .footer { display: flex; + flex-direction: column; justify-content: center; - max-width: 80%; + align-items: center; margin: auto; padding: var(--spacing-xl); font-size: var(--font-small); @@ -9,10 +10,39 @@ @media (max-width: $breakpoint-small) { max-width: 100%; padding: var(--spacing-m); - flex-direction: column; + align-items: flex-start; } } +.footer__links { + display: flex; + flex-direction: column; + + .navigation-link { + font-size: var(--font-small); + } + + .button__label { + color: var(--color-text-help); + } + + .footer__link { + margin-left: 0; + } + + @media (min-width: $breakpoint-small) { + flex-direction: row; + + .footer__link { + margin-left: var(--spacing-m); + } + } +} + +.footer__link { + margin-bottom: var(--spacing-s); +} + .footer__section { margin-left: var(--spacing-xl); @@ -23,7 +53,6 @@ .footer__section-title { @extend .help; - font-weight: 300; margin-bottom: var(--spacing-m); } diff --git a/ui/scss/component/_form-field.scss b/ui/scss/component/_form-field.scss index ffbe29d27..823b63732 100644 --- a/ui/scss/component/_form-field.scss +++ b/ui/scss/component/_form-field.scss @@ -214,6 +214,7 @@ input-submit { border-left: 2px solid; border-bottom: 2px solid; border-color: var(--color-input-toggle); + border-left-color: var(--color-input-toggle); transform: rotate(-45deg); left: 6px; top: 6px; @@ -240,7 +241,7 @@ input-submit { height: 12px; width: 12px; border-radius: 50%; - background-color: var(--color-secondary); + background-color: var(--color-primary); left: 6px; top: 5px; } @@ -356,7 +357,6 @@ fieldset-group { text-overflow: ellipsis; overflow: hidden; padding: 0.5rem; - padding-right: var(--spacing-s); height: var(--height-input); border: 1px solid; border-top-left-radius: var(--border-radius); diff --git a/ui/scss/component/_header.scss b/ui/scss/component/_header.scss index 28d97d503..d8baf78ef 100644 --- a/ui/scss/component/_header.scss +++ b/ui/scss/component/_header.scss @@ -16,7 +16,7 @@ .header--minimal { box-shadow: none; - background-color: transparent; + background-color: var(--color-background); border-bottom: none; } @@ -58,7 +58,6 @@ justify-content: center; align-items: center; border-radius: var(--border-radius); - color: var(--color-text); position: relative; font-weight: var(--font-weight-bold); @@ -135,11 +134,25 @@ } .header__navigation-item--lbry { - padding: var(--spacing-s); + height: 4rem; + display: flex; + align-items: center; + margin-left: var(--spacing-m); + margin-right: var(--spacing-m); - .lbry-icon { - height: var(--height-button); - width: var(--height-button); + @media (max-width: $breakpoint-small) { + margin-right: var(--spacing-m); + height: 5rem; + + .button__label { + display: none; + } + } +} + +.header--minimal { + .header__navigation-item--lbry { + height: 3rem; } } diff --git a/ui/scss/component/_icon.scss b/ui/scss/component/_icon.scss index ac717ecbd..2fa17f490 100644 --- a/ui/scss/component/_icon.scss +++ b/ui/scss/component/_icon.scss @@ -66,3 +66,17 @@ .icon__lbc--title { margin-bottom: 4px; } + +.icon--Fire { + position: relative; + + &:after { + content: ''; + height: 20px; + width: 20px; + background-color: red; + top: 0; + right: 0; + position: absolute; + } +} diff --git a/ui/scss/component/_main.scss b/ui/scss/component/_main.scss index 4d825ffb0..bd11101c9 100644 --- a/ui/scss/component/_main.scss +++ b/ui/scss/component/_main.scss @@ -113,6 +113,7 @@ @media (max-width: $breakpoint-small) { margin-left: 0; + margin-top: var(--spacing-s); } @media (max-width: $breakpoint-medium) { @@ -139,6 +140,7 @@ padding-right: 0; margin-left: 0; margin-right: 0; + margin-top: 0; width: 100vw; max-width: none; diff --git a/ui/scss/component/_markdown-preview.scss b/ui/scss/component/_markdown-preview.scss index 21c77aab6..60013a975 100644 --- a/ui/scss/component/_markdown-preview.scss +++ b/ui/scss/component/_markdown-preview.scss @@ -258,7 +258,7 @@ } .file-viewer__embedded-header { - padding: 0; + padding: var(--spacing-xxs); } } diff --git a/ui/scss/component/_media.scss b/ui/scss/component/_media.scss index 6c11d4961..e58ddd4eb 100644 --- a/ui/scss/component/_media.scss +++ b/ui/scss/component/_media.scss @@ -39,12 +39,6 @@ align-self: flex-start; color: var(--color-text-subtitle); font-size: var(--font-small); - - .channel-thumbnail { - display: inline-block; - @include handleChannelGif(1rem); - margin-right: var(--spacing-xs); - } } .media__subtitle--centered { @@ -115,7 +109,6 @@ position: relative; display: flex; flex-wrap: wrap; - justify-content: space-between; margin-top: 0; > *:not(:last-child) { @@ -123,7 +116,6 @@ } @media (max-width: $breakpoint-small) { - justify-content: flex-start; padding-top: var(--spacing-s); > * { @@ -138,4 +130,9 @@ font-size: var(--font-xxsmall); display: flex; flex-direction: column; + margin-bottom: var(--spacing-s); + + &:not(:last-child) { + margin-bottom: var(--spacing-s); + } } diff --git a/ui/scss/component/_navigation.scss b/ui/scss/component/_navigation.scss index c315f8f7c..65cb34311 100644 --- a/ui/scss/component/_navigation.scss +++ b/ui/scss/component/_navigation.scss @@ -26,7 +26,10 @@ height: calc(100vh - var(--header-height)); border-right: 1px solid var(--color-border); padding-top: var(--spacing-l); - padding-bottom: var(--spacing-xl); + padding-bottom: var(--spacing-l); + overflow-y: auto; + display: flex; + flex-direction: column; @media (min-width: $breakpoint-small) { overflow-y: hidden; @@ -35,6 +38,10 @@ overflow-y: auto; } } + + @media (min-width: $breakpoint-small) { + justify-content: space-between; + } } .navigation--mac { @@ -222,7 +229,16 @@ @extend .navigation-links; margin-right: 0; padding-right: 0; - font-size: var(--font-small); + margin-top: var(--spacing-xl); + margin-bottom: 0; + + .navigation-link { + font-size: var(--font-small); + } + + .button__label { + color: var(--color-text-help); + } .button__content { align-items: flex-start; diff --git a/ui/scss/component/_nudge.scss b/ui/scss/component/_nudge.scss index 551b1adde..46e2ecce2 100644 --- a/ui/scss/component/_nudge.scss +++ b/ui/scss/component/_nudge.scss @@ -1,7 +1,7 @@ .nudge { z-index: 3; position: absolute; - left: 0; + // left: 5rem; top: 4rem; white-space: normal; overflow: visible; @@ -10,6 +10,7 @@ box-shadow: var(--card-box-shadow); background-color: var(--color-secondary); color: var(--color-white); + font-weight: bold; .button--close { .icon { diff --git a/ui/scss/component/_purchase.scss b/ui/scss/component/_purchase.scss index dc3d28a99..0608d7fcb 100644 --- a/ui/scss/component/_purchase.scss +++ b/ui/scss/component/_purchase.scss @@ -55,6 +55,7 @@ .credit-amount { margin: 0 var(--spacing-m); + margin-bottom: -0.5rem; } &::before { diff --git a/ui/scss/component/_search.scss b/ui/scss/component/_search.scss index c65023dfc..7b33d429a 100644 --- a/ui/scss/component/_search.scss +++ b/ui/scss/component/_search.scss @@ -15,6 +15,7 @@ color: var(--color-secondary); margin-bottom: var(--spacing-s); padding: var(--spacing-xxs); + border-radius: var(--border-radius); } fieldset:not(:first-child) { @@ -34,6 +35,7 @@ .search__top-link { margin-top: var(--spacing-s); font-weight: var(--font-weight-body); + margin-top: var(--spacing-xs); } .search__top-links { diff --git a/ui/scss/component/_table.scss b/ui/scss/component/_table.scss index 85910ff7d..711e9fdaa 100644 --- a/ui/scss/component/_table.scss +++ b/ui/scss/component/_table.scss @@ -7,11 +7,11 @@ overflow: hidden; &:first-of-type { - padding-left: var(--spacing-l); + padding-left: var(--spacing-m); } &:last-of-type { - padding-right: var(--spacing-l); + padding-right: var(--spacing-m); } } @@ -102,7 +102,7 @@ th { .table__header-text { width: 100%; - margin: 0 var(--spacing-s); + margin: 0 var(--spacing-xs); } .table__header-text--between { diff --git a/ui/scss/component/_wunderbar.scss b/ui/scss/component/_wunderbar.scss index 3eabf08ca..e89a3e2ad 100644 --- a/ui/scss/component/_wunderbar.scss +++ b/ui/scss/component/_wunderbar.scss @@ -228,6 +228,7 @@ @extend .button--alt; @extend .header__navigation-item--icon; padding: var(--spacing-xs); + margin-right: var(--spacing-m); .button__label { color: var(--color-input-placeholder); diff --git a/ui/scss/component/nag.scss b/ui/scss/component/nag.scss index d247d4d00..8e9b5dca8 100644 --- a/ui/scss/component/nag.scss +++ b/ui/scss/component/nag.scss @@ -37,7 +37,7 @@ $nag-error-z-index: 999; } .nag--helpful { - background-color: var(--color-secondary); + background-color: var(--color-primary); color: var(--color-white); z-index: $nag-helpful-z-index; } @@ -82,7 +82,6 @@ $nag-error-z-index: 999; .nag__button--helpful { &:hover { - background-color: var(--color-secondary-alt); color: var(--color-secondary); } } diff --git a/ui/scss/component/section.scss b/ui/scss/component/section.scss index 2fce62c60..3fdbf6d9c 100644 --- a/ui/scss/component/section.scss +++ b/ui/scss/component/section.scss @@ -41,7 +41,7 @@ .section__title { text-align: left; - font-size: var(--font-title); + font-size: var(--font-large); font-weight: var(--font-weight-light); } @@ -114,10 +114,10 @@ position: relative; display: flex; align-items: center; - margin-top: var(--spacing-l); + margin-top: var(--spacing-m); ~ .section { - margin-top: var(--spacing-l); + margin-top: var(--spacing-m); } &:only-child, diff --git a/ui/scss/init/_color.scss b/ui/scss/init/_color.scss index 5b1fd4e52..201a12060 100644 --- a/ui/scss/init/_color.scss +++ b/ui/scss/init/_color.scss @@ -14,6 +14,12 @@ --color-focus: #93cff2; --color-notification: #f02849; + --color-fire: #ff6635; + --color-fire-outside: #ff6635; + --color-glow: #ffd73550; + --color-slime: #81c554; + --color-success: #009e65; + --color-black: #111; --color-white: #fdfdfd; --color-white-alt: #fafafa; @@ -31,19 +37,6 @@ // Components // Button - --color-button-primary-bg: var(--color-primary); - --color-button-primary-text: var(--color-primary-alt); - --color-button-primary-bg-hover: var(--color-primary-alt-2); - --color-button-primary-hover-text: var(--color-primary-alt); - --color-button-secondary-bg: var(--color-secondary-alt); - --color-button-secondary-border: var(--color-secondary-alt); - --color-button-secondary-text: var(--color-secondary); - --color-button-secondary-bg-hover: #b9d0e9; - --color-button-alt-bg: var(--color-gray-1); - --color-button-alt-text: var(--color-text); - --color-button-alt-bg-hover: var(--color-gray-2); - --color-link: var(--color-primary); - --color-link-hover: var(--color-black); // Input --color-input-color: #111111; @@ -59,10 +52,4 @@ // Table --color-table-highlight: var(--color-white-alt); - - // Tag - --color-tag: var(--color-gray-5); - --color-tag-bg: var(--color-button-alt-bg); - --color-tag-hover: var(--color-button-alt-text); - --color-tag-bg-hover: var(--color-button-alt-bg-hover); } diff --git a/ui/scss/init/_gui.scss b/ui/scss/init/_gui.scss index be1225020..ed8174656 100644 --- a/ui/scss/init/_gui.scss +++ b/ui/scss/init/_gui.scss @@ -60,8 +60,12 @@ ol { position: relative; list-style-position: outside; margin: var(--spacing-xs) 0; - margin-left: var(--spacing-xl); + margin-left: var(--spacing-s); margin-bottom: 0; + + @media (min-width: $breakpoint-small) { + margin-left: var(--spacing-xl); + } } } @@ -242,10 +246,10 @@ textarea { margin-top: var(--spacing-s); &:not(:last-child) { - margin-bottom: var(--spacing-s); + margin-bottom: var(--spacing-m); } - .button--link ~ .button--link { + .button--link + .button--link { margin-left: var(--spacing-s); } @@ -449,3 +453,16 @@ textarea { height: 4rem; } } + +.home__meme { + text-align: center; + font-weight: bold; + line-height: 1; + font-size: 1rem; + margin-bottom: var(--spacing-m); + + @media (min-width: $breakpoint-small) { + font-size: 1.2rem; + margin-bottom: var(--spacing-l); + } +} diff --git a/ui/scss/init/_vars.scss b/ui/scss/init/_vars.scss index e31f3dc1a..58ce6e5af 100644 --- a/ui/scss/init/_vars.scss +++ b/ui/scss/init/_vars.scss @@ -8,7 +8,7 @@ $breakpoint-medium: 1150px; $breakpoint-large: 1600px; :root { - --border-radius: 5px; + --border-radius: 10px; --height-input: 2.5rem; --height-button: 2.5rem; --height-checkbox: 24px; diff --git a/ui/scss/themes/dark.scss b/ui/scss/themes/dark.scss index e692394a7..081568e4c 100644 --- a/ui/scss/themes/dark.scss +++ b/ui/scss/themes/dark.scss @@ -5,45 +5,46 @@ /* #5a6570; - 25% */ [theme='dark'] { - --color-primary-alt: #3e675d; - --color-primary: #2bbb90; + --color-primary: #e50054; + --color-primary-alt: #66001880; + --color-fire: #ff6635; + --color-fire-outside: #ff9b20; // Button --color-link: var(--color-primary); - --color-link-hover: #60e1ba; - --color-link-active: #60e1ba; + --color-link-hover: #d75673; + --color-link-active: #ec1d4c; --color-navigation-icon: #76808a; --color-navigation-link: #b9c3ce; - --color-navigation-active: #333a41; - --color-navigation-active-text: #bac5d0; - --color-navigation-hover: #272c32; - --color-navigation-hover-text: #bac5d0; + --color-navigation-active: #2b2037; + --color-navigation-active-text: #c6bcd2; + --color-navigation-hover: #21182a; + --color-navigation-hover-text: #c6bcd2; - --color-button-primary-bg: var(--color-primary-alt); - --color-button-primary-bg-hover: #44796c; --color-button-primary-text: white; - --color-button-primary-hover-text: var(--color-text); - --color-button-secondary-bg: #395877; - --color-button-secondary-border: #395877; - --color-button-secondary-bg-hover: #4b6d8f; - --color-button-secondary-text: #a3c1e0; - --color-button-alt-bg: #33383d; - --color-button-alt-bg-hover: #3e464d; + --color-button-primary-hover-text: var(--color-primary-alt); + --color-button-secondary-bg: #2c1543; + --color-button-secondary-border: #4f1c82; + --color-button-secondary-bg-hover: #3b1c5b; + --color-button-secondary-text: #efefef; + --color-button-alt-bg: #241a2d; + --color-button-alt-bg-hover: #2b2037; + --color-button-alt-text: #e2e9f0; - --color-header-button: #434b54; - --color-button-border: var(--color-gray-5); - --color-link-focus-bg: #333a41; + --color-header-button: #2b2037; + --color-button-border: #3d2d4e; + --color-button-toggle-bg-hover: var(--color-primary-alt); + --color-button-toggle-text: var(--color-text); + --color-link-focus-bg: #3d2d4e; // Color - --color-focus: #2d69a5; - --color-background-overlay: #212529d7; - --color-background: #1c1f22; - --color-background-overlay: #21252999; - --color-border: #2f3337; - --color-card-background: #232629; - --color-card-background-highlighted: #384046; - --color-header-background: #2a2e32; + --color-background: #0a070d; + --color-background-overlay: #0c0d0e95; + --color-border: #21182a; + --color-card-background: #140e1b; + --color-card-background-highlighted: #2b2037; + --color-header-background: #140f1a; --color-tab-text: var(--color-white); --color-tabs-background: var(--color-card-background); --color-tab-divider: var(--color-white); @@ -54,12 +55,14 @@ --color-error: #61373f; --color-purchased: #ffd580; --color-purchased-alt: var(--color-purchased); - --color-purchased-text: var(--color-gray-5); + --color-purchased-text: black; --color-comment-highlighted: #484734; --color-thumbnail-background: var(--color-gray-5); - --color-comment-threadline: #434b54; + --color-comment-threadline: #24192f; --color-comment-threadline-hover: var(--color-gray-4); --color-tooltip-bg: #2f3337; + --color-focus: #e91e6329; + --color-placeholder-background: #0f0b14; // Text --color-text: #d8d8d8; @@ -79,7 +82,7 @@ --color-input: #f4f4f5; --color-input-label: #a7a7a7; --color-input-placeholder: #f4f4f5; - --color-input-bg: #464d53; + --color-input-bg: #2b2037; --color-input-bg-copyable: #4f5861; --color-input-border: var(--color-border); --color-input-border-active: var(--color-secondary); @@ -91,29 +94,26 @@ // Menu --color-menu-background: var(--color-header-background); - --color-menu-background--active: #3a4045; - --color-menu-icon: #a7a7a7; - --color-menu-icon-active: #464d53; + --color-menu-background--active: var(--color-primary-alt); + --color-menu-icon: #928b9b; + --color-menu-icon-active: #d6d6d6; // Table - --color-table-highlight: #3a444e; + --color-table-highlight: #1a151e; // Search --color-search-suggestion: var(--color-text); - --color-search-suggestion-background: #313d46; - --color-placeholder-background: #4e5862; - --color-spinner-light: #5a6570; + --color-search-suggestion-background: var(--color-primary-alt); + --color-spinner-light: white; --color-spinner-dark: #212529; --color-wunderbar: #89939e; // Tags - --color-tag: var(--color-primary); - --color-tag-bg: var(--color-primary-alt); + --color-tag: #ff85b1; + --color-tag-bg: var(--color-navigation-hover); --color-tag-hover: var(--color-white); --color-tag-bg-hover: var(--color-primary-alt-2); - - // Snack - --color-snack-bg: var(--color-secondary); + --color-tag-mature-bg: var(--color-primary-alt-2); // Editor --color-editor-cursor: var(--color-text); diff --git a/ui/scss/themes/light.scss b/ui/scss/themes/light.scss index 50d7f549c..dfa1bce03 100644 --- a/ui/scss/themes/light.scss +++ b/ui/scss/themes/light.scss @@ -1,4 +1,16 @@ :root { + --color-primary: #fa6165; + --color-primary-alt: #fef1f6; + --color-primary-alt-2: #fb7e82; + --color-primary-alt-3: #fbcbdd; + --color-secondary: #f9902a; + --color-secondary-alt: #fee8d2; + --color-secondary-alt-2: #fefcf6; + + // Button + --color-button-alt-bg: var(--color-gray-1); + --color-button-alt-bg-hover: var(--color-gray-2); + --color-button-alt-text: black; --color-navigation-icon: var(--color-gray-5); --color-link-active: var(--color-primary); --color-navigation-link: var(--color-gray-5); @@ -8,22 +20,45 @@ --color-navigation-hover-text: #3f3f3f; --color-link-focus-bg: #f1f1f1; - --color-header-button: var(--color-button-alt-bg); + --color-link: var(--color-primary); + --color-button-primary-bg: var(--color-primary); + --color-button-primary-bg-hover: var(--color-primary-alt-2); + --color-button-primary-text: var(--color-primary-alt); + --color-button-primary-hover-text: var(--color-white); + --color-button-secondary-bg: var(--color-primary-alt); + --color-button-secondary-border: var(--color-primary-alt-3); + --color-button-secondary-text: var(--color-primary); + --color-button-secondary-bg-hover: var(--color-primary-alt-3); + --color-button-toggle-text: var(--color-primary); + --color-button-toggle-bg: var(--color-primary-alt); + --color-button-toggle-bg-hover: var(--color-primary-alt); --color-button-border: var(--color-gray-3); + --color-button-toggle-text: var(--color-primary); + --color-button-toggle-bg: var(--color-primary-alt); + --color-button-toggle-bg-hover: var(--color-primary-alt); + --color-header-button: var(--color-button-alt-bg); + + // Input + --color-input-bg-selected: var(--color-primary-alt); + --color-input-toggle: var(--color-primary); + --color-input-toggle-bg: var(--color-secondary-alt-2); + --color-input-toggle-bg-hover: var(--color-primary-alt-3); // Color --color-background: #fafafa; + --color-focus: #8dbff0; + --color-background--splash: #212529; --color-border: #ededed; --color-background-overlay: #21252980; - --color-nag: #f26522; + --color-nag: #fa8700; --color-error: #fcafca; --color-comment-menu: #e0e0e0; --color-comment-menu-hovering: #6a6a6a; --color-notice: #fef3ca; --color-purchased: var(--color-cost); --color-purchased-alt: #ffebc2; - --color-purchased-text: var(--color-gray-5); + --color-purchased-text: black; --color-comment-highlighted: #fff2d9; --color-comment-threadline: var(--color-gray-1); --color-comment-threadline-hover: var(--color-gray-4); @@ -38,8 +73,9 @@ --color-view-icon: var(--color-secondary); // Text - --color-text-selection-bg: var(--color-secondary-alt); - --color-text-selection: var(--color-secondary); + --color-text-selection-bg: var(--color-primary-alt); + --color-text-selection: var(--color-primary); + --color-text-error: var(--color-danger); --color-text-empty: #999999; --color-text-help: #999999; @@ -58,7 +94,7 @@ --color-placeholder-background: #f0f0f0; --color-header-background: #ffffff; --color-card-background: #ffffff; - --color-card-background-highlighted: #f1f7fe; + --color-card-background-highlighted: #fff5f5; --color-list-header: #fff; --color-file-viewer-background: var(--color-card-background); --color-tabs-background: var(--color-card-background); @@ -67,17 +103,17 @@ // Menu --color-menu-background: var(--color-header-background); - --color-menu-background--selected: var(--color-secondary-alt); - --color-menu-background--active: #f0f7ff; --color-menu-icon: var(--color-navigation-link); --color-menu-icon-active: var(--color-navigation-link); + --color-menu-background--selected: var(--color-secondary-alt); + --color-menu-background--active: var(--color-primary-alt); // Search --color-search-suggestion: #212529; --color-search-suggestion-background: #cce6fb; // Snack - --color-snack-bg: var(--color-primary); + --color-snack-bg: var(--color-success); --color-snack: var(--color-white); --color-snack-bg-error: var(--color-danger); --color-snack-upgrade: var(--color-tertiary); @@ -98,6 +134,12 @@ --color-editor-hr: var(--color-editor-tag); --color-editor-hr-preview: #cccccc; + // Tag + --color-tag: var(--color-primary-alt-2); + --color-tag-bg: #f9f6f7; + --color-tag-hover: var(--color-button-alt-text); + --color-tag-bg-hover: var(--color-button-alt-bg-hover); + // Ads --color-ads-background: #fae5ff; --color-ads-link: var(--color-link); diff --git a/ui/util/query-params.js b/ui/util/query-params.js index 7acf507c6..5f52733a2 100644 --- a/ui/util/query-params.js +++ b/ui/util/query-params.js @@ -1,5 +1,4 @@ // @flow -import { SEARCH_OPTIONS } from 'constants/search'; const DEFAULT_SEARCH_RESULT_FROM = 0; const DEFAULT_SEARCH_SIZE = 20; @@ -35,36 +34,38 @@ export const getSearchQueryString = (query: string, options: any = {}) => { const encodedQuery = encodeURIComponent(query); const queryParams = [ `s=${encodedQuery}`, + `free_only=true`, `size=${options.size || DEFAULT_SEARCH_SIZE}`, `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`, + // `mediaType=${SEARCH_OPTIONS.MEDIA_VIDEO}`, + // `claimType=${SEARCH_OPTIONS.INCLUDE_FILES}`, ]; - const { isBackgroundSearch } = options; - const includeUserOptions = typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch; + // const { isBackgroundSearch } = options; + // const includeUserOptions = typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch; - if (includeUserOptions) { - const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; - if (claimType) { - queryParams.push(`claimType=${claimType}`); + // if (includeUserOptions) { + // const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; + // if (claimType) { + // queryParams.push(`claimType=${claimType}`); - /* - * Due to limitations in lighthouse, we can't pass - * the mediaType parameter when searching for - * channels or "everything". - */ - if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { - queryParams.push( - `mediaType=${[ - SEARCH_OPTIONS.MEDIA_FILE, - SEARCH_OPTIONS.MEDIA_AUDIO, - SEARCH_OPTIONS.MEDIA_VIDEO, - SEARCH_OPTIONS.MEDIA_TEXT, - SEARCH_OPTIONS.MEDIA_IMAGE, - SEARCH_OPTIONS.MEDIA_APPLICATION, - ].reduce((acc, currentOption) => (options[currentOption] ? `${acc}${currentOption},` : acc), '')}` - ); - } - } - } + /* + * Due to limitations in lighthouse, we can't pass + * the mediaType parameter when searching for + * channels or "everything". + */ + // if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { + // queryParams.push( + // `mediaType=${[ + // SEARCH_OPTIONS.MEDIA_FILE, + // SEARCH_OPTIONS.MEDIA_AUDIO, + // SEARCH_OPTIONS.MEDIA_VIDEO, + // SEARCH_OPTIONS.MEDIA_TEXT, + // SEARCH_OPTIONS.MEDIA_IMAGE, + // SEARCH_OPTIONS.MEDIA_APPLICATION, + // ].reduce((acc, currentOption) => (options[currentOption] ? `${acc}${currentOption},` : acc), '')}` + // ); + // } + // } const additionalOptions = {}; const { related_to } = options; diff --git a/web/component/fileViewerEmbeddedEnded/view.jsx b/web/component/fileViewerEmbeddedEnded/view.jsx index eaf70ee30..420ef9359 100644 --- a/web/component/fileViewerEmbeddedEnded/view.jsx +++ b/web/component/fileViewerEmbeddedEnded/view.jsx @@ -4,7 +4,7 @@ import Button from 'component/button'; import { formatLbryUrlForWeb } from 'util/url'; import { withRouter } from 'react-router'; import { URL, SITE_NAME } from 'config'; -import * as ICONS from 'constants/icons'; +import OdyseeLogoWithText from 'component/header/odysee_white.png'; type Props = { uri: string, @@ -37,7 +37,9 @@ function FileViewerEmbeddedEnded(props: Props) { return ( <div className="file-viewer__overlay"> <div className="file-viewer__overlay-secondary"> - <Button className="file-viewer__overlay-logo" label="LBRY" icon={ICONS.LBRY} href={URL} /> + <Button className="file-viewer__overlay-logo--videoend" href={URL}> + <img src={OdyseeLogoWithText} /> + </Button> </div> <div className="file-viewer__overlay-title">{prompt}</div> <div className="file-viewer__overlay-actions"> diff --git a/web/component/footer.jsx b/web/component/footer.jsx index 37ce1e645..ead0a6507 100644 --- a/web/component/footer.jsx +++ b/web/component/footer.jsx @@ -1,102 +1,37 @@ // @flow -import * as PAGES from 'constants/pages'; +// import * as PAGES from 'constants/pages'; import React from 'react'; import Button from 'component/button'; - -const sections = [ - { - name: 'Community', - links: [ - { - label: 'Twitter', - link: 'https://twitter.com/lbrycom', - }, - { - label: 'Reddit', - link: 'https://reddit.com/r/lbry', - }, - { - label: 'Chat (Discord)', - link: 'https://chat.lbry.org/', - }, - { - label: 'Telegram', - link: 'https://t.me/lbryofficial', - }, - { - label: 'Facebook', - link: 'https://www.facebook.com/lbryio', - }, - ], - }, - { - name: 'Resources', - links: [ - { - label: 'FAQ', - link: 'https://lbry.com/faq', - }, - { - label: 'Support --[used in footer; general help/support]--', - link: 'https://lbry.com/faq/support', - }, - { - label: 'YouTube Partner Program', - link: 'https://lbry.com/youtube', - }, - { - label: 'lbry.com', - link: 'https://lbry.com', - }, - { - label: 'lbry.tech', - link: 'https://lbry.tech', - }, - { - label: 'GitHub', - link: 'https://github.com/lbryio', - }, - ], - }, - { - name: 'Policies', - links: [ - { - label: 'Terms of Service', - link: 'https://www.lbry.com/termsofservice', - }, - { - label: 'Privacy Policy', - link: 'https://lbry.com/privacypolicy', - }, - { - label: '2257', - navigate: `/$/${PAGES.CODE_2257}`, - }, - ], - }, -]; +import I18nMessage from 'component/i18nMessage'; export default function Footer() { return ( <footer className="footer"> - {sections.map(({ name, links }) => { - return ( - <div key={name} className="footer__section"> - <div className="footer__section-title">{__(name)}</div> - <ul className="ul--no-style"> - {/* $FlowFixMe */} - {links.map(({ label, link, navigate }) => { - return ( - <li key={label}> - <Button className="footer__link" href={link} navigate={navigate} label={__(label)} /> - </li> - ); - })} - </ul> - </div> - ); - })} + <span className="footer__section-title"> + <I18nMessage tokens={{ lbry_link: <Button button="link" label={'LBRY'} href="https://lbry.com" /> }}> + POWERED BY %lbry_link% + </I18nMessage> + </span> + <ul className="navigation__tertiary footer__links"> + <li className="footer__link"> + <Button label={__('About --[link title in Sidebar or Footer]--')} href="https://lbry.com/about" /> + </li> + <li className="footer__link"> + <Button label={__('Community Guidelines')} href="https://odysee.com/@OdyseeHelp:b/Community-Guidelines:c" /> + </li> + <li className="footer__link"> + <Button label={__('FAQ')} href="https://odysee.com/@OdyseeHelp:b" /> + </li> + <li className="footer__link"> + <Button label={__('Support --[used in footer; general help/support]--')} href="https://lbry.com/support" /> + </li> + <li className="footer__link"> + <Button label={__('Terms')} href="https://lbry.com/termsofservice" /> + </li> + <li className="footer__link"> + <Button label={__('Privacy Policy')} href="https://lbry.com/privacy" /> + </li> + </ul> </footer> ); }