From 62dd21a4b70e6455ebb871a3730685b9b89117a6 Mon Sep 17 00:00:00 2001 From: Ogoun Date: Thu, 13 Jun 2024 19:34:44 +0300 Subject: [PATCH] Web update --- src/BukiVedi.App/BukiVedi.App.csproj | 93 ++++---- .../Controllers/BooksController.cs | 11 + .../Debug/net8.0/BukiVedi.App.AssemblyInfo.cs | 2 +- .../BukiVedi.App.AssemblyInfoInputs.cache | 2 +- ...ukiVedi.App.csproj.AssemblyReference.cache | Bin 10429 -> 10429 bytes .../BukiVedi.App.csproj.FileListAbsolute.txt | 13 +- .../obj/Debug/net8.0/BukiVedi.App.pdb | Bin 30216 -> 30344 bytes src/BukiVedi.App/web/README.md | 12 + src/BukiVedi.App/web/assets/fortune.svg | 1 + src/BukiVedi.App/web/css/common.css | 14 ++ src/BukiVedi.App/web/css/logo.css | 2 +- src/BukiVedi.App/web/css/main.css | 104 +++++++-- src/BukiVedi.App/web/index.html | 10 +- .../web/js/components/menu/index.js | 112 ++++++++++ .../web/js/components/tags/index.js | 61 ++++-- src/BukiVedi.App/web/js/constants/index.js | 57 ++++- src/BukiVedi.App/web/js/main/index.js | 206 ++++++++---------- src/BukiVedi.App/web/js/requests/index.js | 22 +- src/BukiVedi.App/web/js/utils/index.js | 8 +- src/BukiVedi.App/web/script.js | 24 +- src/BukiVedi.App/web/server.js | 52 ----- src/BukiVedi.Shared/Apps/BooksHandler.cs | 7 + src/BukiVedi.Shared/Apps/IBooksHandler.cs | 1 + src/BukiVedi.Shared/IRepository.cs | 2 +- src/BukiVedi.Shared/Services/Library.cs | 27 ++- .../Services/MongoDB/MongoRepository.cs | 7 + .../bin/Debug/net8.0/BukiVedi.Shared.pdb | Bin 45136 -> 45628 bytes .../net8.0/BukiVedi.Shared.AssemblyInfo.cs | 2 +- .../BukiVedi.Shared.AssemblyInfoInputs.cache | 2 +- .../obj/Debug/net8.0/BukiVedi.Shared.pdb | Bin 45136 -> 45628 bytes 30 files changed, 559 insertions(+), 295 deletions(-) create mode 100644 src/BukiVedi.App/web/README.md create mode 100644 src/BukiVedi.App/web/assets/fortune.svg create mode 100644 src/BukiVedi.App/web/js/components/menu/index.js delete mode 100644 src/BukiVedi.App/web/server.js diff --git a/src/BukiVedi.App/BukiVedi.App.csproj b/src/BukiVedi.App/BukiVedi.App.csproj index e347a66..8f94c30 100644 --- a/src/BukiVedi.App/BukiVedi.App.csproj +++ b/src/BukiVedi.App/BukiVedi.App.csproj @@ -6,29 +6,6 @@ enable - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - @@ -40,6 +17,9 @@ Always + + Always + Always @@ -52,10 +32,31 @@ Always - + Always - + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + Always @@ -74,60 +75,54 @@ Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest + Always - PreserveNewest - - Always - - PreserveNewest - - + Always Always - + Always @@ -136,9 +131,6 @@ Always - - PreserveNewest - Always @@ -160,6 +152,9 @@ Always + + Always + Always diff --git a/src/BukiVedi.App/Controllers/BooksController.cs b/src/BukiVedi.App/Controllers/BooksController.cs index 394e7bc..170249b 100644 --- a/src/BukiVedi.App/Controllers/BooksController.cs +++ b/src/BukiVedi.App/Controllers/BooksController.cs @@ -36,6 +36,17 @@ namespace BukiVedi.App.Controllers return Ok(await _handler.Search(request.Query, tag, OperationContext)); } + /// + /// Поиск книг по запросу + /// + /// Поисковый запрос + /// Список найденных книг + [HttpPost("qsearch")] + public async Task>> SearchAI() + { + return Ok(await _handler.SearchAI(OperationContext)); + } + #endregion /// diff --git a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfo.cs b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfo.cs index 4c7f986..d4b7992 100644 --- a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfo.cs +++ b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("BukiVedi.App")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+78ef654d3cca93dcdff7557d9a44da30b9d10a6a")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+708729b3f0a4a46b4ed8277753e30266f9b02ae4")] [assembly: System.Reflection.AssemblyProductAttribute("BukiVedi.App")] [assembly: System.Reflection.AssemblyTitleAttribute("BukiVedi.App")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfoInputs.cache b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfoInputs.cache index 40cf07e..d26e675 100644 --- a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfoInputs.cache +++ b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.AssemblyInfoInputs.cache @@ -1 +1 @@ -9dd3a16a8dacdbe5f2cc466ad40a08504afd3b209bf5aa3244617367acdb74bb +5d627d5604365b2a4254a699545c17a9cb8aa8618ee125b742c4fb1f29d8de02 diff --git a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.csproj.AssemblyReference.cache b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.csproj.AssemblyReference.cache index d44087fa40f2d608217cb5bf874d8b96648ddc61..c1dcec0f472f7e94cd70fe11087a7846bd27b289 100644 GIT binary patch delta 17 YcmdlRxHoV@5}Wqg`u1bp8#6*R07&i!+5i9m delta 17 YcmdlRxHoV@5}TyJ?oRFIjTxaD06^IW#sB~S diff --git a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.csproj.FileListAbsolute.txt b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.csproj.FileListAbsolute.txt index 3a4911b..0e16737 100644 --- a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.csproj.FileListAbsolute.txt +++ b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.csproj.FileListAbsolute.txt @@ -88,10 +88,19 @@ G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\js\requests\i G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\js\scroll\index.js G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\script.js G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\assets\pencil.svg -G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\js\common\jquery.min.js G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\js\components\tags\index.js G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\js\utils\index.js G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\loginScript.js -G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\server.js G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\LemmaSharpPrebuilt.pdb G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\LemmaSharpPrebuilt.dll.config +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\assets\fortune.svg +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Raleway-Italic-VariableFont_wght.ttf +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Raleway-VariableFont_wght.ttf +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Roboto-300.ttf +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Roboto-300.woff +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Roboto-300.woff2 +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Roboto-400.ttf +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Roboto-400.woff +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\css\fonts\Roboto-400.woff2 +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\js\components\menu\index.js +G:\Documents\GitHub\BukiVedi\src\BukiVedi.App\bin\Debug\net8.0\web\README.md diff --git a/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.pdb b/src/BukiVedi.App/obj/Debug/net8.0/BukiVedi.App.pdb index fde160a36b56f9462d00d90b80b05e4b328f9461..a8741c36bd848319f84e215a9170ba3b937fb4da 100644 GIT binary patch delta 4025 zcmb_fdstLu9{!yfn3;1x1OYEZFWlg~zNy6<<8@zmeW!|(mx_x*kM@0&A+ zm%bNXx+82Dl6%pYC~_&$$K8lh2z*9$W$A*FDo`RnA}{XEoIzgTPR_^8oREgH4f;PN z&|}IL7C@`cy=mS5>NgYLT*4-MA5c#_RYm7FZU{;rfZRpIPQ+BiQwWnl)QU(2*C2cl z!H6Wpa0F5mfzTt=h>06-M+Wl_tO(wqH-dNc0t**b*)N$v(aANl58X!GL;M%<0O6g* zb2{?P(orBH1QGto>kB>*k%Sm2dm{P}(T7NBSt4c1o&-;V$NSOH^ehb}XLHU!8d{ev z_|SFPP?2C^`Kq8GHN9c!%=77+bG>M8E)tQfTqSyWcZ%M2EhSpDG##-6u@7;KFORhJ z<)iXjx$N{d&+h7xml{gX>ntb9WhXDP@sfW83eWFkI2hWe;6HS6I}*|S;N*{rW+-^0 zhj-=GwBO^YDXOr`_o7k-->%@N6A|Dn}VP7a9-D& zbaOh(?sD15XW@c&e!OXgg6}V(_5iQ0HdA9|cZheJfsk^LCTKLiSK=3;x(9&G~r0j|4g~-IWcnVw-h2yv*aKzC#)>s^+ z0ms)DCl*JgcIt>n` z!U9KPQAXN9&ypU~-fGrk;%z`3wVMsNkwsbqzI_d%5!v_5Mr4lzb#&JJH$hE*QGX$@ zTaurBNVeV!k58bE=42be%Yj;23e?exY#W@j*-qdOIZikoId1S)iyM5Wg}gZ@Z_f2H z*UQ`p++(rH=!8Ea*9kr<*9D#i)Y2rNj;7ml-LNnTjfQUJ>NUKQ5xmu61m9_~0ryxO zGCE~+$>^4mv>LjXOIjU0%+&+;Sd22-WOO3iYH@<^w79^%tS+sV!ht$6Slx2g?v~S} zlh>h>hXl{GI)GcOHc>;3vu&bCvw#xKpY4J(GS3C4Cs3lOJcp#ADK>{B(r@4rJ#BNt z@y~a|xd<-NU7OKILv8s+ACano60OO1!nu*}w8OfPPre!oEg)Z!{0eL`w}Gb@xWI4Z zyTBI}=)3Vc`fehlZ|pA8Ple9zc6k;Mh9dIkocu+~DYAio0u<>LphT|~x#X-1&d){q0A5ocAX5Kg z2Y53OQv^!1ve*qLw7?DLAH~KVyr!{-NFBu#sG-p%6e!ZEITR?-y*ai(jUH8Pu%0h* zAst%a0^ePt50cj!B+}>Yi@W_K=#MYIk~VQ|*8IA0fk|Zzu9o*YULSkTH2v?ZPwS^O z6|DHCeQoz`UiQO=V4~z1xp0 z{#VJhpXctKS8G^z^~Dzw#|?dM|Ms_!U*Wxcbz`Gs`O^=fyjus6^5^_JoRhxu;bG+c6BVd>#iwW z_g2xJvEP1hDC6*$tKXd(bYaKn*0t7#(3L$`9vyabmieDaC$bLyvZA)R{ak9F)%y!l zuYYMQ%4&&O+|t_Cyss$XwZ<2tL)%YX{@OC*mlq#cPZ}mj4<~mVUUy>0(d>tFFE6?> za$T>Zrs!15gcPxT>HNi)oiTk)_xjY_9YyVjg14x8zny-vm5c&?ACmS}#;<)R?tA6b zUq?UO65Kwww=~&)NN|zq0*9XfGyOQkahSrPmcwQa?{GNC;T(s{9By;y0L4DQg?ubNbXFZ_@~FOCwyJsxA^5GB z+DF8XFWyqyx0WP5@kwO!{mha0fS#Gin~)RE6X_ggOG1#aEJj#X_H+oFTAE>d(x<`C zKpx)GOCFTnFHL;zNe{x$`0*O$m06B*ua#|lZhY|*9!}m@`EvbkVWZ|{3VODBUYHQh zUZ3}}5W&Wj)k>LRc&QnM$YjUL`U#QjPFa&Mh1JcE6{6Vg`G*5d{3YcM!lcIAOBlk$ zsuqkFqS=uJcFDX1O}8V=EPdf%A%-npI9tlu2jdJPhh1IRS1>TCJi*th3l)Ne2)rnV z^<^35alW=r1NSVfAFD5qQx`_Xvc2UA>N#O?>}%-K5%J8oVw|vmnJNrIf3~Dz&@&Y} z%!K%xp*B>Aa2zFy;{Psc`JXV3ov4WERvk6aX! Cf|;`b delta 3955 zcmb_fYgiL!8hwXAk{LimE+SqM?jopwH^5s2t$<*$2m}b41QEQTNW6Bb30@wpvWiYx zT^2N2yN})K>Wa5MYK?2vYHO=@b+z4Uth?&EV!LXqbVc`kgT`5ZI}h)fbI$wS=Ka3R zGpuaoR^H_r1{&&ph$0pf)%p@86L{X-nrX8tETFU(o+tD2^XMSBgYmKXnWJ&ncOu$d z0i8B;wi!Agd+%4D>>HbNq;Y!lfzy*7v~AmbWnDwyn7+t;gV=-^j|fHNaYXMSQo)r7 zZ$uDcAcA>FQ8+?_P#`ka{VO7f4N!t$9YPRnpao(W_pbFyAt(lM6?)Sx#685%h$jez zp5@de=+)$p2tjC`d(q&15d#rJC6C7#JjUQDP0v%NYjb+OW=OKMW^|rP!5>7%tNz#dWF( zYZ~$|TBM^zI+XHxk5ka2p;gay0Q4A{WMRcg5K=*(p zC|$Kow;^vq4PPvnO*sD*z33HP`--;8HRh)!GGj3&TrSgRkYD+VUMw?f2AK|GC2Euz-$FNw|KwAwfrY59^qS)6Q@s~Bdqc4SIkFVku#J7Nburkk-c(L; zRB5GHY(+nmzb{HY0A(Ibizta|@iw*6AXIG#DwT}tq|$0iL={r-q{H!a!|*^OshLKQ z7E9h(sKuhU0@d{A!WbMsvnmF^vN~Re?14fZvd4jHI#;-#Q_x3>OTbH>)?aY@$;+is zQc{uD6K_bMnx+)#z-IwfR0~wo(jp_Ab43o|-C_rvN5wAi<`NgUqlCN|Cojge64y#x z2mG+aD4_#>iopRs%-{r1GdQhYD$0UTQ?9`U3yV-H>83%eWQ}w{be7O2p+iEagf6ta zXK;bH8%V`kY9-W3Xj8ET*}xqo4sefBhe|~npqipeol@4Rva+;G5-zE!POYTOQX|k_ zs^gWkY?6-WX(CXd8Iv4vhE8_C2?PohKG`TJDcfiic=|86K;4Z_IGs#RIG4Z$YBg%T zm9*8Q_2#JtDA2nm8=M1AM-je3?(aJZ&>O zz=O&h;P=1}sqz=I8g?1MZmagzs~H_R}8{LPid+s}A)f+9{TdJDw1D>YCTl&x7xjrzZYU#A3nhC$Q<_w7q=pSgfZx^kLZ#5?Onl-QW-e-wTTNb>nUmw17 z&EvK+m;baPOK)rpIQ+r#@wCXQP>-L{ZQh07>}uN1_d2cLaxpVFYC_|-52o3BMrU5Q zliGSXEq}eQXZ6k%X&FmGyBlx!t;@~sp8n;i@j;*RRTQ*hL0I{2+g~r$^-gX4xUy%N zw%eU0h86RJpEZ29f84=CH+JSm#fScT`-t|p>+gNk5ca!V`!@x@)?a$7`HP$XIHYZ~ zzH{~Lyd$G8e%Ul2{Lz|UlwF_Z59`wP{LD{!+&%j6=JquEh;6-gbl*Gf%sW>!mY~pw zS1$X0-g|HI-KQJ7=U3+KGLLHW{?S;Ied2ubjo7l}oRk}561%O9sa;icGBM|VtR`yV zvi9$<qCga958$H2 zQ?n-tMSEbJM-++ut9x_NqP{x8$Dr=P1##i{8rH;!_UbsF$sGpHnWne+MRlCQ92qON zRVOIQHGRbRIdO{0p>bmIoUvS$xOGkp7cZWflNesD#!85N{;7I!;kF}0k?iYN#s0Wq zJV&WwZcVtaC95f7a8#HZsxePJ}y18qeB4 z$?eV*yIGRBC1SRvPv^)1ZhH|LCyR$I5uKJtvHvqWmSkHi9<;i6S#JKtKibhSUSUf+TYyKZ8yp=ov diff --git a/src/BukiVedi.App/web/README.md b/src/BukiVedi.App/web/README.md new file mode 100644 index 0000000..381f168 --- /dev/null +++ b/src/BukiVedi.App/web/README.md @@ -0,0 +1,12 @@ +# Vanilla JS Project +Vesion 1.0 + +## To run chrome for localhost: +` +"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --disable-gpu --user-data-dir=C:\Users\User\chromeTemp +` + +## To run project for [localhost](http://localhost:3001/login.html): +` +npm start +` \ No newline at end of file diff --git a/src/BukiVedi.App/web/assets/fortune.svg b/src/BukiVedi.App/web/assets/fortune.svg new file mode 100644 index 0000000..5a2500e --- /dev/null +++ b/src/BukiVedi.App/web/assets/fortune.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/BukiVedi.App/web/css/common.css b/src/BukiVedi.App/web/css/common.css index 96e5e2b..fc24cb1 100644 --- a/src/BukiVedi.App/web/css/common.css +++ b/src/BukiVedi.App/web/css/common.css @@ -76,6 +76,11 @@ input { margin-bottom: 12px; } +.mv-m { + margin-top: 20px; + margin-bottom: 20px; +} + .mt-m { margin-top: 20px; } @@ -130,6 +135,10 @@ input { padding-right: 12px; } +.pt-l { + padding-top: 40px; +} + /** * display forms **/ @@ -138,6 +147,11 @@ input { display: flex; } +.justify-c { + display: flex; + justify-content: center; +} + .d-bl { display: block; } diff --git a/src/BukiVedi.App/web/css/logo.css b/src/BukiVedi.App/web/css/logo.css index 83bf784..392e184 100644 --- a/src/BukiVedi.App/web/css/logo.css +++ b/src/BukiVedi.App/web/css/logo.css @@ -1,7 +1,7 @@ .background-logo { position: absolute; - top: -15px; + top: 25px; left: 20px; z-index: -1; overflow: hidden; diff --git a/src/BukiVedi.App/web/css/main.css b/src/BukiVedi.App/web/css/main.css index a894743..cda42a1 100644 --- a/src/BukiVedi.App/web/css/main.css +++ b/src/BukiVedi.App/web/css/main.css @@ -34,10 +34,16 @@ header { width: 20px; height: 100%; left: 10px; - top: 15px; + top: 55px; opacity: 0.25; } +.main-search-btn-wrapper { + position: absolute; + right: 5px; + top: 43px; +} + .main-search { display: block; width: 100%; @@ -47,6 +53,7 @@ header { border-radius: 14px; border-style: solid; border-width: 1px; + padding-right: 200px; } .main-search:hover { @@ -67,20 +74,23 @@ header { .main-search-btn { display: block; - margin-left: auto; - margin-right: auto; - max-width: 200px; - width: 200px; - height: 50px; + visibility: hidden; + max-width: 120px; + width: 120px; + height: 44px; min-width: 80px; background: var(--main-font-color); color: var(--main-bg-color); - font-size: 21px; + font-size: 17px; line-height: 25px; border-radius: 15px; cursor: pointer; } +.main-search-btn.visible { + visibility: visible; +} + .main-search-btn:hover { opacity: 0.9; } @@ -96,6 +106,61 @@ header { margin-right: auto; } +#fortuneButton { + background-color: transparent; + background-image: url(../assets/fortune.svg); + background-repeat: no-repeat; + width: 40px; + height: 40px; + border: 0; + margin-left: 12px; + margin-top: 3px; + position: relative; + transform-origin: center center; + +} + +#fortuneButton:hover { + cursor: pointer; + animation: antiClockwiseSpin 1s linear; + transform-origin: center center; +} + +#fortuneButton:active { + transform: translateY(2px); +} + +@keyframes antiClockwiseSpin { + 0% { + transform: rotate(180deg); + } + 100% { + transform: rotate(0deg); + } +} + +@keyframes antiClockwiseSpin { + 0% { + transform: rotate(180deg); + } + 100% { + transform: rotate(0deg); + } +} +/* +#fortuneButton:hover:after { + content: "Мне повезет!"; + color: var(--main-font-color); + width: 95px; + font-size: 13px; + padding: 5px; + border-radius: 5px; + background: #fff; + position: absolute; + opacity: 1; + z-index: 2; +} */ + /*======================================================== Book Section ========================================================*/ @@ -139,6 +204,7 @@ header { .main-book__card.card_closed { max-height: 450px; + min-height: 285px; overflow-y: hidden; } @@ -316,7 +382,7 @@ header { padding-bottom: 4px; background: #fff; line-height: 28px; - width: 200px; + width: 230px; vertical-align: middle; } @@ -342,7 +408,7 @@ header { .main-book__tags_title { position: relative; - width: 55px; + width: 113px; font-family: Vedi, Verdana, Tahoma; font-size: 14px; line-height: 24px; @@ -355,17 +421,23 @@ header { color: var(--active-color); } .pencil { - position: absolute; - top: 4px; - left: 40px; background-image: url(../assets/pencil.svg); background-repeat: no-repeat; width: 20px; - height: 100%; + height: 20px; + margin-left: 12px; + margin-top: 4px; } -.main-book__tags_title:hover, -.main-book__tags_title:active .pencil { +.main-book__pencil { + position: absolute; + top: 0; + left: 90px; +} + +.pencil:hover, +.pencil:active { + cursor: pointer; filter: brightness(0) saturate(100%) invert(43%) sepia(34%) saturate(7336%) hue-rotate(202deg) brightness(82%) contrast(97%); } @@ -486,7 +558,7 @@ header { box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; - background-color: #FFF; + background-color: #fff; color: var(--main-font-color); font-size: 14px; font-family: Vedi, Verdana, Tahoma; diff --git a/src/BukiVedi.App/web/index.html b/src/BukiVedi.App/web/index.html index b0bd963..630f46e 100644 --- a/src/BukiVedi.App/web/index.html +++ b/src/BukiVedi.App/web/index.html @@ -22,17 +22,21 @@

Vedi

-
+
+
+ + + +
-
diff --git a/src/BukiVedi.App/web/js/components/menu/index.js b/src/BukiVedi.App/web/js/components/menu/index.js new file mode 100644 index 0000000..c837962 --- /dev/null +++ b/src/BukiVedi.App/web/js/components/menu/index.js @@ -0,0 +1,112 @@ +import { waitForElement } from "../../requests/index.js"; +import { getMenu } from "../../constants/index.js"; +export default class MenuComponent { + element; + constructor({ + isBlocked = false, + hasReadLater = false, + authors = [], + bookid = null, + article, + }) { + this.isBlocked = isBlocked; + this.hasReadLater = hasReadLater; + this.authors = authors; + this.bookid = bookid; + this.article = article; + this.isOpened = false; + this.render(); + } + + get template() { + return ` + `; + } + + initialize() { + this.initEventListeners(); + } + + initEventListeners() { + const menuListener = this.article.querySelector(".main-book__menu"); + + menuListener.addEventListener("click", (event) => { + const isAction = event.target.closest("[data-action]"); + if (!!isAction) { + const id = isAction.dataset.action; + this.makeAction({ id }); + } else { + this.openMenu(); + } + }); + document.addEventListener("menu-outside-click", () => this.closeMenu()); + } + + get actions() { + return getMenu({ + isBlocked: this.isBlocked, + hasReadLater: this.hasReadLater, + }); + } + + getMenuBody() { + return this.actions + .map(({ label, id }) => { + return ` +
  • + ${label} +
  • `; + }) + .join(""); + } + + openMenu() { + this.element.classList.remove("main-book__menu_closed"); + + const ulElement = document.createElement("ul"); + ulElement.innerHTML = this.getMenuBody(); + + this.element.append(ulElement); + this.element.classList.add("main-book__menu_opened"); + this.isOpened = true; + } + + closeMenu() { + if (this.isOpened) { + this.element.classList.remove("main-book__menu_opened"); + this.element.firstElementChild.remove(); + this.element.classList.add("main-book__menu_closed"); + this.isOpened = false; + } + } + + async makeAction({ id }) { + this.article.classList.add("blur", "spinner"); + + const { action, value } = + this.actions.find((act) => act.id === Number(id)) || {}; + + await action({ id, bookid: this.bookid }); + + if (value) { + const { id, label } = value; + this[`${id}`] = label; + } + + this.article.classList.remove("spinner"); + this.closeMenu(); + } + + async waitRendered() { + await waitForElement(".main-book__menu"); + this.initialize(); + } + + async render() { + const divElement = document.createElement("div"); + divElement.innerHTML = this.template; + + this.element = divElement.firstElementChild; + this.waitRendered(); + } +} diff --git a/src/BukiVedi.App/web/js/components/tags/index.js b/src/BukiVedi.App/web/js/components/tags/index.js index 83d7ad5..d71211e 100644 --- a/src/BukiVedi.App/web/js/components/tags/index.js +++ b/src/BukiVedi.App/web/js/components/tags/index.js @@ -11,27 +11,37 @@ export default class TagsComponent { } get template() { - return ` -
    - Теги -
    -
    -
    ${this.getTags( - this.tags - )}
    - `; + return `
    + ${ + !(this.tags && this.tags.length) + ? this.getTitle() + : this.getTags(this.tags) + } +
    `; + } + + getTitle() { + return `
    + Добавить теги +
    +
    `; } + getTags(tags) { - return (tags || []) + return `
    + ${(tags || []) .map(({ id, name }) => { return `#${name}`; }) - .join(""); + .join("")} +
    `; } getTextarea(tags) { return ` - `; @@ -42,15 +52,13 @@ export default class TagsComponent { } initEventListeners() { - const tagsEditorListener = this.article.querySelector( - ".main-book__tags_title" - ); + const tagsEditorListener = this.article.querySelector(".main-book_edit"); tagsEditorListener.addEventListener("click", () => { - const tagsWrapper = this.article.querySelector(".main-book__tags"); - if (!this.isTextareaMode) { + const tagsWrapper = this.article.querySelector(".main-book_edit"); tagsWrapper.innerHTML = this.getTextarea(this.tags); + this.article.querySelector(".main-book__textarea").focus(); this.isTextareaMode = true; } @@ -64,7 +72,7 @@ export default class TagsComponent { } }); - document.addEventListener("outside-click", async () => { + document.addEventListener("tag-outside-click", async () => { if (this.isTextareaMode) { this.closeTextarea(); } @@ -72,22 +80,31 @@ export default class TagsComponent { } async closeTextarea() { - const tagsWrapper = this.article.querySelector(".main-book__tags"); + const tagsWrapper = this.article.querySelector(".main-book_edit"); const area = this.article.querySelector(".main-book__textarea"); const tags = area.value .split(" ") .map((item) => item.trim()) .filter((i) => i); - if (!!(tags || []).length > 0) { + + if ( + this.tags?.length !== tags?.length || + (this.tags || []).some(({ name }, index) => name !== tags[index]) + ) { await this.setTags({ bookid: this.bookid, tags }); } - tagsWrapper.innerHTML = this.getTags(this.tags); + + if (!!(tags || []).length > 0) { + tagsWrapper.innerHTML = this.getTags(this.tags); + } else { + tagsWrapper.innerHTML = this.getTitle(); + } this.isTextareaMode = false; } async waitRendered() { - await waitForElement(".main-book__tags"); + await waitForElement(".main-book_edit"); this.initialize(); } diff --git a/src/BukiVedi.App/web/js/constants/index.js b/src/BukiVedi.App/web/js/constants/index.js index 998ca84..30eb98c 100644 --- a/src/BukiVedi.App/web/js/constants/index.js +++ b/src/BukiVedi.App/web/js/constants/index.js @@ -1,40 +1,73 @@ -import * as requests from '../requests/index.js'; +import * as requests from "../requests/index.js"; export const SUCCESS = "success"; -export const menuEnum = [ +export const menuDict = [ { id: 1, - label: "Авторов в избранное", - action: requests.addAuthorToFavourites, + label: "В очередь на чтение", + action: requests.readLater, + value: { + id: 'hasReadLater', + label: true, + } }, { id: 2, - label: "В очередь на чтение", - action: requests.readLater, + label: "Убрать из очереди", + action: requests.removeFromReadLater, + value: { + id: 'hasReadLater', + label: false, + } }, { id: 3, label: "Игнорировать книгу", action: requests.ignoreBook, + value: { + id: 'isBlocked', + label: true, + } }, { id: 4, - label: "Игнорировать автора", - action: requests.ignoreAuthors, + label: "Перестать игнорировать книгу", + action: requests.stopIgnoreBook, + value: { + id: 'isBlocked', + label: false, + } + }, + { + id: 5, + label: "Авторов в избранное", + action: requests.addAuthorToFavourites, }, { id: 6, - label: "Заметка", + label: "Игнорировать авторов", + action: requests.ignoreAuthors, }, { id: 7, + label: "Заметка", + action: () => {}, + }, + { + id: 8, label: "Поделиться", + action: () => {}, }, ]; +export const getMenu = ({ isBlocked, hasReadLater }) => + menuDict + .filter((item) => (isBlocked ? item.id !== 3 : item.id !== 4)) + .filter((item) => (hasReadLater ? item.id !== 1 : item.id !== 2)); + export const DEFAULT_AUTHOR = { id: 0, - name: 'Неизвестно' + name: "Неизвестно", }; export const likeEnum = [ @@ -47,5 +80,5 @@ export const likeEnum = [ id: 1, label: "Не нравится", action: requests.removeBookToFavourites, - } -] \ No newline at end of file + }, +]; diff --git a/src/BukiVedi.App/web/js/main/index.js b/src/BukiVedi.App/web/js/main/index.js index e6fa073..26569a1 100644 --- a/src/BukiVedi.App/web/js/main/index.js +++ b/src/BukiVedi.App/web/js/main/index.js @@ -1,6 +1,7 @@ -import { menuEnum, likeEnum, DEFAULT_AUTHOR } from "../constants/index.js"; +import { likeEnum, DEFAULT_AUTHOR } from "../constants/index.js"; import { fetchData, + fetchRandomData, downloadBook, searchByAuthor, searchByTag, @@ -9,6 +10,7 @@ import { import { stopPropagation } from "../utils/index.js"; import TagsComponent from "../components/tags/index.js"; +import MenuComponent from "../components/menu/index.js"; export default class BookSection { subElements = []; @@ -37,31 +39,22 @@ export default class BookSection { const booksListener = document.querySelector(".main-book__wrapper"); booksListener.addEventListener("click", (event) => { let id, title; + stopPropagation(event); + + const menuEvent = new CustomEvent("menu-outside-click"); + const tagEvent = new CustomEvent("tag-outside-click"); + const isLike = event.target.closest("[data-like]"); - const isMenu = event.target.closest("[data-menu]"); - const isAction = event.target.closest("[data-action]"); const isLink = event.target.closest("[data-link]"); const isAuthor = event.target.closest("[data-author]"); const isMoreDetails = event.target.closest("[data-details]"); - const isTagWrapper = event.target.closest("[data-tags-wrapper]"); + const isTagWrapper = event.target.closest("[data-tags-editor]"); const isTag = event.target.closest("[data-tag]"); - - stopPropagation(event); + const isMenuWrapper = event.target.closest("[data-menu]"); switch (true) { - case !!isAction: - id = isAction.dataset.action; - const { authorid, bookid } = - isAction.parentNode.parentNode.dataset || {}; - this.makeAction({ id, authorid, bookid }); - - break; case !!isLike: this.makeLike(isLike); - break; - - case !!isMenu: - this.openMenu(isMenu); break; case !!isLink: @@ -80,20 +73,21 @@ export default class BookSection { this.toggleDetails(isMoreDetails); break; - case !isTagWrapper: - const myEvent = new CustomEvent("outside-click"); - document.dispatchEvent(myEvent); - this.closeMenu(); - + case !!isMenuWrapper: break; case !!isTag: id = isTag.dataset.tag; this.update({ isByTag: true, id }); - default: - this.closeMenu(); + break; + case !isTagWrapper && !isTag && !isMenuWrapper: + document.dispatchEvent(tagEvent); + document.dispatchEvent(menuEvent); break; + + default: + break; } }); } @@ -128,10 +122,6 @@ export default class BookSection {
    - -
    @@ -170,7 +160,7 @@ export default class BookSection {

    -
    +
    ${description || "Нет описания"} @@ -197,17 +187,6 @@ export default class BookSection { `; } - getMenuBody() { - return menuEnum - .map(({ label, id }) => { - return ` -
  • - ${label} -
  • `; - }) - .join(""); - } - getAuthors(authors) { return (authors || [DEFAULT_AUTHOR]) .map(({ id, name }) => { @@ -217,29 +196,6 @@ export default class BookSection { .join(""); } - openMenu(element) { - this.closeMenu(); - element.classList.remove("main-book__menu_closed"); - - const divElement = document.createElement("ul"); - divElement.innerHTML = this.getMenuBody(); - - element.append(divElement); - element.classList.add("main-book__menu_opened"); - } - - closeMenu() { - const elements = document.querySelectorAll(".main-book__menu_opened"); - - if (elements && elements.length) { - for (const subElement of elements) { - subElement.firstElementChild.remove(); - subElement.classList.remove("main-book__menu_opened"); - subElement.classList.add("main-book__menu_closed"); - } - } - } - toggleDetails(element) { const isOpened = element.classList.contains("opened"); const article = element.parentNode.parentNode; @@ -264,13 +220,23 @@ export default class BookSection { const articles = document.querySelectorAll("[data-card]"); articles.forEach((article, i) => { const tagWrapper = article.querySelector(".main-book__tags_wrapper"); + const menuWrapper = article.querySelector(".main-book__menu_wrapper"); const bookid = article.dataset.bookid; - const { tags } = this.data[i] || []; + const { tags, isBlocked, hasReadLater, authors } = this.data[i] || []; const tagsComponent = new TagsComponent({ tags, article, bookid }); + const menuComponent = new MenuComponent({ + isBlocked, + hasReadLater, + authors, + bookid, + article, + }); tagWrapper.append(tagsComponent.element); + menuWrapper.append(menuComponent.element); + // console.log('article.scrollHeight', article.scrollHeight); - if (article.scrollHeight > 502) { + if (article.scrollHeight > 424) { const arrow = article.querySelector(".main-book__arrow_wrapper"); arrow.classList.remove("hidden"); } @@ -295,27 +261,26 @@ export default class BookSection { const { bookid: likedBookId, like } = element.dataset || {}; const isLiked = like === "true"; - if (!isLiked) { - await likeEnum[0].action({ bookid: likedBookId }); - element.classList.remove("not-liked"); - element.classList.add("liked"); - } else { + if (isLiked) { await likeEnum[1].action({ bookid: likedBookId }); element.classList.remove("liked"); element.classList.add("not-liked"); + } else { + await likeEnum[0].action({ bookid: likedBookId }); + element.classList.remove("not-liked"); + element.classList.add("liked"); } element.dataset.like = !isLiked; this.data = this.data.map(({ isFavorite, id, ...rest }) => likedBookId === id - ? { id, isFavorite: !isFavorite, ...rest } + ? { id, ...rest, isFavorite: !isFavorite } : { id, isFavorite, ...rest, } ); - console.log("new data", this.data); this.element.classList.remove("spinner"); } @@ -326,6 +291,8 @@ export default class BookSection { this.data = await searchByAuthor({ id: params.id }); } else if (params?.isByTag) { this.data = await searchByTag({ id: params.id }); + } else if (params?.isByRandom) { + this.data = await fetchRandomData(); } else { const query = params; this.data = await fetchData({ query, url: this.url }); @@ -335,10 +302,11 @@ export default class BookSection { if (this.data && Object.values(this.data).length) { this.subElements.body.innerHTML = this.getBookBody(this.data); this.initialize(); + await this.countHeight(); } else { this.subElements.body.innerHTML = this.getEmptyBody(); } - await this.countHeight(); + this.element.classList.remove("spinner"); } @@ -375,48 +343,50 @@ export default class BookSection { } } -// this.data = [ -// { -// id: "2", -// authors: [{ id: "1", name: "123" }], -// description: -// "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", -// format: "123", -// genres: [], -// imageUrl: "", -// title: "What is Lorem Ipsum?", -// series: [], -// subseries: [], -// year: 1992, -// tags: [ -// { id: 1, name: "Интересно" }, -// { id: 22, name: "Почитать" }, -// { id: 155, name: "Рекомендовали" }, -// { id: 166, name: "завтра" }, -// { id: 11, name: "наверное" }, -// { id: 221, name: "Почитданетать" }, -// { id: 1515, name: "раздватри" }, -// { id: 1661, name: "возможно" }, -// ], -// isFavorite: true, -// }, -// { -// id: "22", -// authors: [{ id: "1", name: "123" }], -// description: -// "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", -// format: "123", -// genres: [], -// imageUrl: "", -// title: "dsfwqedwqefrwef", -// series: [], -// subseries: [], -// year: 1992, -// tags: [ -// { id: 1, name: "Интересно" }, -// { id: 22, name: "Почитать" }, -// { id: 155, name: "Рекомендовали" }, -// ], -// isFavorite: true, -// }, -// ]; +const testData = [ + { + id: "2", + authors: [{ id: "1", name: "123" }], + description: + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", + format: "123", + genres: [], + imageUrl: "", + title: "What is Lorem Ipsum?", + series: [], + subseries: [], + year: 1992, + tags: [ + { id: 1, name: "Интересно" }, + { id: 22, name: "Почитать" }, + { id: 155, name: "Рекомендовали" }, + { id: 166, name: "завтра" }, + { id: 11, name: "наверное" }, + { id: 221, name: "Почитданетать" }, + { id: 1515, name: "раздватри" }, + { id: 1661, name: "возможно" }, + ], + isFavorite: true, + hasReadLater: true, + isBlocked: true, + }, + { + id: "22", + authors: [{ id: "1", name: "123" }], + description: + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", + format: "123", + genres: [], + imageUrl: "", + title: "dsfwqedwqefrwef", + series: [], + subseries: [], + year: 1992, + tags: [ + { id: 1, name: "Интересно" }, + { id: 22, name: "Почитать" }, + { id: 155, name: "Рекомендовали" }, + ], + isFavorite: true, + }, +]; diff --git a/src/BukiVedi.App/web/js/requests/index.js b/src/BukiVedi.App/web/js/requests/index.js index 36fb7f3..fb03a35 100644 --- a/src/BukiVedi.App/web/js/requests/index.js +++ b/src/BukiVedi.App/web/js/requests/index.js @@ -20,6 +20,24 @@ export const fetchData = ({ query, url }) => { }); }; +export const fetchRandomData = () => { + return $.ajax({ + contentType: "application/json; charset=utf-8", + dataType: "json", + type: "POST", + url: "../api/books/qsearch", + success: function (data, textStatus, jqXHR) { + if (textStatus === SUCCESS) { + return data; + } + return []; + }, + error: function (jqXHR, textStatus, errorThrown) { + console.log(jqXHR.statusText); + }, + }); +}; + export const addBookToFavourites = ({ bookid }) => { return $.ajax({ type: "POST", @@ -221,10 +239,6 @@ export const changeTags = ({ bookid, tags }) => { console.log(jqXHR.statusText); }, }); - - // return [ - // {id: "6611598e1468849d1b00570d", name: "шиза"} - // ]; }; export const searchByTag = ({ id }) => { diff --git a/src/BukiVedi.App/web/js/utils/index.js b/src/BukiVedi.App/web/js/utils/index.js index 9b8387a..b5e63b3 100644 --- a/src/BukiVedi.App/web/js/utils/index.js +++ b/src/BukiVedi.App/web/js/utils/index.js @@ -1,4 +1,4 @@ -export const stopPropagation = event => { - event.stopImmediatePropagation(); - event.stopPropagation(); -} \ No newline at end of file +export const stopPropagation = (event) => { + event.stopImmediatePropagation(); + event.stopPropagation(); +}; diff --git a/src/BukiVedi.App/web/script.js b/src/BukiVedi.App/web/script.js index 4576623..87fbbac 100644 --- a/src/BukiVedi.App/web/script.js +++ b/src/BukiVedi.App/web/script.js @@ -1,14 +1,17 @@ - import BookSection from "./js/main/index.js"; -import ButtonScroll from './js/scroll/index.js'; +import ButtonScroll from "./js/scroll/index.js"; const input = document.getElementById("search"); const books = document.getElementById("books"); const content = document.getElementById("content"); +const searchButton = document.getElementById("searchButton"); +const fortuneButton = document.getElementById("fortuneButton"); + const booksSection = new BookSection({ url: "../api/books/search", label: "books", }); + const click = () => { const query = document.getElementById("search").value; if (query) { @@ -16,8 +19,19 @@ const click = () => { } }; -searchButton.addEventListener("click", click); +const fortuneClick = () => { + booksSection.update({ isByRandom: true }); +}; +searchButton.addEventListener("click", click); +fortuneButton.addEventListener("click", fortuneClick); +input.addEventListener("input", function (e) { + if (e.target.value && e.target.value.length !== 0) { + searchButton.classList.add("visible"); + } else { + searchButton.classList.remove("visible"); + } +}); input.addEventListener("keypress", function (event) { if (event.key === "Enter") { click(); @@ -25,5 +39,5 @@ input.addEventListener("keypress", function (event) { }); books.append(booksSection.element); -const scroll = new ButtonScroll() -content.append(scroll.element) \ No newline at end of file +const scroll = new ButtonScroll(); +content.append(scroll.element); diff --git a/src/BukiVedi.App/web/server.js b/src/BukiVedi.App/web/server.js deleted file mode 100644 index fe8a538..0000000 --- a/src/BukiVedi.App/web/server.js +++ /dev/null @@ -1,52 +0,0 @@ -const path = require('path'); -const { createProxyMiddleware } = require('http-proxy-middleware'); -const cors = require('cors'); - -const express = require('express'); -const app = express(); - -const server = require('http').Server(app); -const router = require('express').Router() - -const options = { - target: 'https://book.ogoun.name/', // target host - changeOrigin: true, // needed for virtual hosted sites - ws: true, // proxy websockets - logLevel: 'debug', - secure: false, - cookieDomainRewrite: { - '*': 'localhost', - }, - onProxyRes(proxyRes, req, _res) { - if (proxyRes.headers['set-cookie'] !== undefined) { - req.cookie = proxyRes.headers['set-cookie']; - } - }, - onProxyReq(proxyReq, req, _res) { - if (req && req.cookie !== undefined) { - proxyReq.setHeader('Cookie', req.cookie[0]); - } - }, -}; - -const myLogger = function (req, res, next) { - next() -} - -app.use(myLogger) - -app.use(express.static(__dirname)); -app.use(express.static(__dirname + '/js')); -app.use(express.static(__dirname + '/css')); -app.use(express.static(__dirname + '/constants')); - -// app.get('/login', function (req, res) { -// res.sendFile(path.join(__dirname, '/login.html')); -// }); - -app.use('/', cors({ - credentials: true, - origin: 'http://localhost:3000', -}), createProxyMiddleware(options)); - -server.listen(3001); \ No newline at end of file diff --git a/src/BukiVedi.Shared/Apps/BooksHandler.cs b/src/BukiVedi.Shared/Apps/BooksHandler.cs index bb52744..0486e26 100644 --- a/src/BukiVedi.Shared/Apps/BooksHandler.cs +++ b/src/BukiVedi.Shared/Apps/BooksHandler.cs @@ -2,6 +2,7 @@ using BukiVedi.Shared.Models; using BukiVedi.Shared.Services; using BukiVedi.Shared.Services.Mappers; +using ZeroLevel.Patterns.Queries; using ZeroLevel.Services.FileSystem; namespace BukiVedi.Shared.Apps @@ -176,6 +177,12 @@ namespace BukiVedi.Shared.Apps return Enumerable.Empty(); } + public async Task> SearchAI(OperationContext context) + { + var books = (await _library.SearchBooksAI(context.OperationInitiator.Id)).ToArray(); + return await BookEntityMapper.Map(books, context); + } + public async Task UnblockBook(string id, OperationContext context) { var account_id = context.OperationInitiator.Id; diff --git a/src/BukiVedi.Shared/Apps/IBooksHandler.cs b/src/BukiVedi.Shared/Apps/IBooksHandler.cs index f166ae5..97c256f 100644 --- a/src/BukiVedi.Shared/Apps/IBooksHandler.cs +++ b/src/BukiVedi.Shared/Apps/IBooksHandler.cs @@ -5,6 +5,7 @@ namespace BukiVedi.Shared.Apps public interface IBooksHandler { Task> Search(string query, string? tag, OperationContext context); + Task> SearchAI(OperationContext context); Task AddToFavorite(string id, OperationContext context); Task AddAuthorsToFavorite(string id, OperationContext context); Task BlockBook(string id, OperationContext context); diff --git a/src/BukiVedi.Shared/IRepository.cs b/src/BukiVedi.Shared/IRepository.cs index a219803..e81b70d 100644 --- a/src/BukiVedi.Shared/IRepository.cs +++ b/src/BukiVedi.Shared/IRepository.cs @@ -16,7 +16,7 @@ namespace BukiVedi.Shared Task Count(FilterDefinition predicate); Task Exists(FilterDefinition filter); Task ExistById(string id); - + T[] GetRandomDocuments(int count); Task Write(T obj); diff --git a/src/BukiVedi.Shared/Services/Library.cs b/src/BukiVedi.Shared/Services/Library.cs index 41a118e..a707924 100644 --- a/src/BukiVedi.Shared/Services/Library.cs +++ b/src/BukiVedi.Shared/Services/Library.cs @@ -13,6 +13,7 @@ namespace BukiVedi.Shared.Services { Task> SearchBooksByAuthor(string author_id); Task> SearchBooks(string title); + Task SearchBooksAI(string accountId); Task> SearchByTagBooks(string accountId, string tagId); Task> SearchTaggedBooks(string accountId, string tag = null!); Task> SearchFavoritesBooks(string accountId); @@ -96,7 +97,7 @@ namespace BukiVedi.Shared.Services public async Task> SearchFavoritesBooks(string accountId) { - + IEnumerable bookIds = (await Tables.FavoriteBooks.Get(Filters.FavoriteBooks.ByUser(accountId)))?.Select(t => t.BookId)?.ToHashSet()!; if (bookIds != null && bookIds.Any()) { @@ -149,7 +150,7 @@ namespace BukiVedi.Shared.Services { IEnumerable bookIds; if (string.IsNullOrWhiteSpace(tag)) - { + { bookIds = (await Tables.UserTag.Get(Filters.Tags.ByUser(accountId)))?.Select(t => t.BookId)?.ToHashSet()!; } else @@ -439,5 +440,27 @@ namespace BukiVedi.Shared.Services await Tables.Books.Write(book); } } + + public Task SearchBooksAI(string accountId) + { + var books = Tables.Books.GetRandomDocuments(50); + var result = new BookEntity[books.Length]; + int index = 0; + foreach (var b in books) + { + result[index] = new BookEntity + { + Authors = GetAuthors(b), + Title = b.Title, + Year = b.Year, + Description = b.Description, + Format = b.Format, + Genre = new Genre(), + Id = b.Id, + }; + index++; + } + return Task.FromResult(result); + } } } diff --git a/src/BukiVedi.Shared/Services/MongoDB/MongoRepository.cs b/src/BukiVedi.Shared/Services/MongoDB/MongoRepository.cs index 3c54efc..30156b3 100644 --- a/src/BukiVedi.Shared/Services/MongoDB/MongoRepository.cs +++ b/src/BukiVedi.Shared/Services/MongoDB/MongoRepository.cs @@ -1,6 +1,7 @@ using BukiVedi.Shared.Entities; using MongoDB.Bson; using MongoDB.Driver; +using MongoDB.Driver.Linq; using System.Linq.Expressions; using ZeroLevel.Services.FileSystem; @@ -104,6 +105,12 @@ namespace BukiVedi.Shared.Services.MongoDB return result.ToEnumerable().ToArray(); } + public T[] GetRandomDocuments(int count) + { + var result = _collection.AsQueryable().Sample(count); + return result.ToArray(); + } + public async Task Count(FilterDefinition filter) { return await _collection.CountDocumentsAsync(filter); diff --git a/src/BukiVedi.Shared/bin/Debug/net8.0/BukiVedi.Shared.pdb b/src/BukiVedi.Shared/bin/Debug/net8.0/BukiVedi.Shared.pdb index 538f7b28a5641458cb8105c6d511bd3ff53a3f69..da2fa327355a8b764bf298e79797aaa95621f01f 100644 GIT binary patch delta 17871 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 diff --git a/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfo.cs b/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfo.cs index 133b6ef..034f311 100644 --- a/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfo.cs +++ b/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("BukiVedi.Shared")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+78ef654d3cca93dcdff7557d9a44da30b9d10a6a")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+708729b3f0a4a46b4ed8277753e30266f9b02ae4")] [assembly: System.Reflection.AssemblyProductAttribute("BukiVedi.Shared")] [assembly: System.Reflection.AssemblyTitleAttribute("BukiVedi.Shared")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfoInputs.cache b/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfoInputs.cache index 8c5b692..6274847 100644 --- a/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfoInputs.cache +++ b/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.AssemblyInfoInputs.cache @@ -1 +1 @@ -43fea615f27b115ca71adae9d28aa42c583a4dce3ecf8ac2e68c45249fa1eb8e +47f2ecfa029d676b8f2f23a9542e5f91afdb2a5aba3b39b9691101443bb7f9e8 diff --git a/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.pdb b/src/BukiVedi.Shared/obj/Debug/net8.0/BukiVedi.Shared.pdb index 538f7b28a5641458cb8105c6d511bd3ff53a3f69..da2fa327355a8b764bf298e79797aaa95621f01f 100644 GIT binary patch delta 17871 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