index.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. import {
  2. actionAboutMe,
  3. actionAllPostsUser,
  4. actionAboutUser,
  5. actionPostsFeed,
  6. actionPostsFeedCount,
  7. actionOnePost,
  8. actionAddComment,
  9. actionAddLike,
  10. actionDeleteLike,
  11. actionPostsCount,
  12. actionAuthLogout,
  13. actionRegister,
  14. actionGetAvatar,
  15. actionAddSubComment,
  16. actionAllClearPromise,
  17. actionAvatar,
  18. actionLogin,
  19. actionAuthLogin,
  20. actionClearPromise,
  21. actionGetCommentsOnePost,
  22. actionFindLikes,
  23. actionPostUpsert,
  24. actionClearPromiseForName,
  25. actionChangeSubscribe,
  26. actionGetFollowing,
  27. actionGetFollowers,
  28. actionUserUpsert,
  29. actionAllClearPromiseType,
  30. actionFindSubComment
  31. // actionOnePost
  32. } from '../../actions'
  33. import { message } from 'antd'
  34. import { actionClearAboutMeType } from '../reducers/myProfileReducer'
  35. import { history } from '../../helpers'
  36. import {
  37. actionClearDataUserType,
  38. actionChangeFollowersType,
  39. actionUserAllPostsType,
  40. actionPostsType
  41. } from '../reducers/userProfileReducer'
  42. import { actionProfilePageDataType,actionChangeFollowingType } from '../reducers/myProfileReducer'
  43. import { actionFullAllGetPosts } from '../../actions'
  44. import {
  45. actionAddLikePostInTape,
  46. actionDeleteLikePostInTape,
  47. actionAddCommentPostInTape,
  48. actionClearFeedPosts,
  49. actionFeedType,
  50. actionClearFeedPostsType,
  51. actionAddCommentPostFeedType,
  52. actionAddLikePostFeedType
  53. } from '../reducers/feedReducer'
  54. import { actionProfilePageDataTypeUser,actionCountPostsType } from '../reducers/userProfileReducer'
  55. import { actionRemoveDataAboutMe,actionUpdateAvatarType } from '../reducers/myProfileReducer'
  56. import {actionExploreType,actionClearExplorePosts} from '../reducers/exploreReducer'
  57. import { all, put,take, fork, takeEvery, takeLatest, takeLeading, select,call, join } from 'redux-saga/effects'; //
  58. import {actionPending,actionFulfilled,actionRejected,actionExplorePosts,actionExplorePostsCount} from '../../actions'
  59. import { actionOnePostType, actionChangeLikeType } from '../../actions/types/postActionTypes'
  60. import {actionAddCommentType,actionAddSubCommentType} from '../../actions/types/postActionTypes'
  61. import { actionAddSubCommentTypeSaga } from '../../actions/typeSaga/postActionSaga'
  62. //promise
  63. export function* promiseWorker(action){ //это типа actionPromise который thunk
  64. const {name, promise} = action
  65. yield put(actionPending(name)) //это как dispatch
  66. try {
  67. let data = yield promise //а это как await
  68. yield put(actionFulfilled(name, data))
  69. return data //а этот результать можно забрать через yield call(promiseWorker, actionPromise(......) /*какой-то объект action*/)
  70. }
  71. catch (error) {
  72. yield put(actionRejected(name, error))
  73. }
  74. }
  75. export function* promiseWatcher(){
  76. yield takeEvery('PROMISE_START', promiseWorker)
  77. }
  78. //login
  79. function* loginWorker({login, password}){ //обработчик экшона FULL_LOGIN
  80. let token = yield call(promiseWorker,actionLogin(login, password)) //dispatch(actionLogin(login, password));
  81. console.log('token login ', token)
  82. if (token) {
  83. yield put(actionAuthLogin(token));
  84. }
  85. }
  86. export function* loginWatcher() {
  87. yield takeEvery("FULL_LOGIN", loginWorker)
  88. }
  89. export const actionLoginTypeSaga = (login, password) => //упрощенный action для саги
  90. ({type: 'FULL_LOGIN', login, password})
  91. //register
  92. function* registerWorker({ login, password }) {
  93. let token = yield call(promiseWorker,actionRegister(login, password)) //dispatch(actionLogin(login, password));
  94. console.log('token reg ', token)
  95. if (token) {
  96. console.log('token reg в ифе ', token)
  97. yield put(actionLoginTypeSaga(login, password ))
  98. history.push('/feed')
  99. }
  100. }
  101. export function* registerWatcher() {
  102. yield takeEvery("REGISTER", registerWorker)
  103. }
  104. export const actionRegisterTypeSaga = (login, password) => //упрощенный action для саги
  105. ({type: 'REGISTER', login, password})
  106. //profile page about me
  107. export const actionFullProfilePage = () =>
  108. ({
  109. type:"FULLPROFILE_PAGE",
  110. })
  111. function* fullProfilePageWorker() {
  112. const { auth } = yield select()
  113. // console.log('auth', auth)
  114. if (auth?.payload?.sub?.id) {
  115. const aboutMe = yield call(promiseWorker, actionAboutMe(auth?.payload?.sub.id))
  116. // console.log('aboutMe in worker', aboutMe)
  117. if (aboutMe) {
  118. yield put(actionProfilePageDataType(aboutMe))
  119. }
  120. }
  121. }
  122. export function* fullProfilePageWatcher() {
  123. yield takeEvery("FULLPROFILE_PAGE", fullProfilePageWorker)
  124. }
  125. //aboutUser
  126. //full profile user
  127. export const actionFullProfilePageUser = (_id) =>
  128. ({ type: "USER_PAGE", _id })
  129. function* fullPageAboutUserWorker({ _id }) {
  130. // console.log('_id ', _id)
  131. const aboutUser = yield call(promiseWorker, actionAboutUser(_id))
  132. // console.log('about user', aboutUser)
  133. const allPosts = yield call(promiseWorker, actionAllPostsUser(_id))
  134. const countPosts = yield call(promiseWorker, actionPostsCount(_id))
  135. if (aboutUser)
  136. yield put(actionProfilePageDataTypeUser(aboutUser))
  137. if(allPosts) {
  138. yield put(actionUserAllPostsType(allPosts))
  139. }
  140. if (countPosts)
  141. yield put(actionCountPostsType(countPosts))
  142. }
  143. export function* fullPageAboutUserWatcher() {
  144. yield takeLeading("USER_PAGE", fullPageAboutUserWorker)
  145. }
  146. function* feedWorker() {
  147. const {
  148. feed: { postsFeed, postsFeedCount },
  149. myData: { aboutMe},
  150. } = yield select()
  151. let myFollowing = aboutMe?.following && aboutMe?.following?.map(({ _id }) => _id)
  152. const myId = (yield select()).auth?.payload?.sub?.id
  153. if (!aboutMe) {
  154. yield call(fullProfilePageWorker, actionFullProfilePage())
  155. }
  156. myFollowing = (yield select()).myData.aboutMe?.following &&
  157. (yield select()).myData.aboutMe?.following?.map(({ _id }) => _id)
  158. // console.log('myFollowing after if', myFollowing)
  159. if (postsFeed?.length !== (postsFeedCount ? postsFeedCount : 1)) {
  160. const newPosts = yield call(promiseWorker,
  161. actionPostsFeed([...(myFollowing || []), myId], postsFeed?.length),
  162. )
  163. console.log('newPosts', newPosts)
  164. const newPostsFeedCount = yield call(promiseWorker, (
  165. actionPostsFeedCount([...(myFollowing || []), myId])))
  166. if (newPosts && newPostsFeedCount) {
  167. console.log('newPosts', newPosts)
  168. yield put(actionFeedType(newPosts, newPostsFeedCount))
  169. }
  170. }
  171. }
  172. export function* feedWatcher() {
  173. yield takeLeading("FEED_POSTS", feedWorker)
  174. }
  175. function* postsWorker({_id}) {
  176. const {
  177. userData: {aboutUser, allPosts,countPosts },
  178. // myData: { aboutMe },
  179. // promise:{countAllPostsUser:{payload}}
  180. } = yield select()
  181. if (allPosts?.length !== (countPosts ? countPosts : 1)) {
  182. const newPosts = yield call(promiseWorker,
  183. actionAllPostsUser(_id, allPosts?.length),
  184. )
  185. const newPostsCount = yield call(promiseWorker,
  186. actionPostsCount(_id))
  187. if (newPosts && newPostsCount) {
  188. yield put(actionPostsType(newPosts, newPostsCount))
  189. }
  190. }
  191. }
  192. export function* postsWatcher() {
  193. yield takeLeading("USER_POSTS_PORTION", postsWorker)
  194. }
  195. //explore
  196. function* exploreWorker(){
  197. const {
  198. explore: { explorePosts, explorePostsCount },
  199. } = yield select()
  200. console.log('explorePosts', explorePosts)
  201. if (explorePosts?.length !== (explorePostsCount ? explorePostsCount : 1)) {
  202. console.log('explorePosts', explorePosts)
  203. const newPosts = yield call(promiseWorker,
  204. actionExplorePosts(explorePosts?.length))
  205. console.log('newPosts', newPosts)
  206. const newPostsExploreCount = yield call(promiseWorker, (actionExplorePostsCount()))
  207. if (newPosts && newPostsExploreCount)
  208. yield put(actionExploreType(newPosts, newPostsExploreCount))
  209. }
  210. }
  211. export function* exploreWatcher() {
  212. yield takeLeading("EXPLORE_POSTS", exploreWorker)
  213. }
  214. // export const actionAddFullCommentFeed = (postId, newResult) => async (
  215. // dispatch,
  216. // getState,
  217. // ) => {
  218. // await dispatch(actionAddComment(postId, newResult))
  219. // const {
  220. // promise: {
  221. // addComment: { status },
  222. // },
  223. // } = getState()
  224. // if (status === 'FULFILLED') {
  225. // const onePost = await dispatch(actionOnePost(postId))
  226. // if (onePost) await dispatch(actionAddCommentPostInTape(postId, newResult))
  227. // }
  228. // // await dispatch(actionOnePost(postId));
  229. // }
  230. //one post
  231. function* onePostWorker({ _id }) {
  232. const onePost = yield call(promiseWorker,actionOnePost(_id))
  233. if (onePost)
  234. yield put(actionOnePostType(onePost))
  235. }
  236. export function* onePostWatcher(){
  237. yield takeLeading("ONE_POST",onePostWorker)
  238. }
  239. //comment
  240. function* addCommentOnePostWorker({ postId, text }) {
  241. yield call(promiseWorker, actionAddComment(postId, text))
  242. const {
  243. promise: {
  244. addComment: { status },
  245. },
  246. } = yield select()
  247. if (status === 'FULFILLED') {
  248. yield call(promiseWorker, actionOnePost(postId))
  249. const { comments } = yield call(promiseWorker, actionGetCommentsOnePost(postId))
  250. if (comments)
  251. yield put (actionAddCommentType(comments))
  252. }
  253. }
  254. export function* addCommentOnePostWatcher(){
  255. yield takeLeading("ONE_POST_COMMENT",addCommentOnePostWorker)
  256. }
  257. function* addCommentFeedWorker({ postId, text }) {
  258. yield call(promiseWorker, actionAddComment(postId, text))
  259. const {
  260. promise: {
  261. addComment: { status },
  262. },
  263. } = yield select()
  264. if (status === 'FULFILLED') {
  265. yield call(promiseWorker, actionOnePost(postId))
  266. const { comments } = yield call(promiseWorker,
  267. actionGetCommentsOnePost(postId))
  268. if (comments)
  269. yield put (actionAddCommentPostFeedType(postId,comments))
  270. }
  271. }
  272. export function* addCommentFeedWatcher(){
  273. yield takeLeading("FEED_POST_COMMENT",addCommentFeedWorker)
  274. }
  275. // export const actionAddFullLike = (postId) => async (dispatch, getState) => {
  276. // await dispatch(actionAddLike(postId))
  277. // const {
  278. // promise: {
  279. // addLike: { status },
  280. // },
  281. // } = getState()
  282. // if (status === 'FULFILLED') {
  283. // const onePost = await dispatch(actionOnePost(postId))
  284. // if (onePost) await dispatch(actionAddLikePostInTape(postId))
  285. // }
  286. // }
  287. //change like in post
  288. export const actionChangeLike = (likeId, postId) =>
  289. ({
  290. type:"CHANGE_LIKE_POST", likeId,postId
  291. })
  292. function* changeLikeWorker({ likeId, postId }) {
  293. console.log('likeId', likeId)
  294. console.log('postId', postId)
  295. const changeOneLike = () =>
  296. likeId ? actionDeleteLike(likeId, postId) : actionAddLike(postId)
  297. yield call(promiseWorker, changeOneLike())
  298. return yield call(promiseWorker, actionFindLikes(postId))
  299. }
  300. function* changeLikePostWorker({ likeId, postId }) {
  301. const { likes } = yield call(changeLikeWorker, {likeId, postId})
  302. if (likes) {
  303. // yield call(promiseWorker, actionOnePost(postId))
  304. yield put(actionChangeLikeType(likes))
  305. }
  306. }
  307. function* changeLikePostFeedWorker({ likeId, postId }) {
  308. const { likes } = yield call(changeLikeWorker, {likeId, postId})
  309. if (likes) {
  310. // yield call(promiseWorker, actionOnePost(postId))
  311. yield put(actionAddLikePostFeedType(likes))
  312. }
  313. }
  314. export function* changeLikePostWatcher() {
  315. yield takeLeading("CHANGE_LIKE_POST", changeLikePostWorker)
  316. }
  317. //change like in post feed
  318. export const actionChangeFeedLike = (likeId, postId) =>
  319. ({
  320. type:"CHANGE_LIKE_POST_FEED", likeId,postId
  321. })
  322. export function* changeLikePostFeedWatcher() {
  323. yield takeLeading("CHANGE_LIKE_POST_FEED", changeLikePostFeedWorker)
  324. }
  325. // create and edit post
  326. function* editPostWorker({state }) {
  327. console.log('in worker default post', state)
  328. console.log('in worker post id', state?._id)
  329. const postUpsert = yield call(promiseWorker, actionPostUpsert(state,state?._id))
  330. console.log('post Upsert', postUpsert)
  331. // postUpsert
  332. // const upsertPost = yield call(promiseWorker, actionPostUpsert(post))
  333. // console.log('upsert POST', upsertPost)
  334. if (postUpsert) {
  335. yield put(actionClearPromiseForName('postUpsert'))
  336. yield put(actionClearPromiseForName('uploadFiles'))
  337. }
  338. }
  339. export function* editPostWatcher() {
  340. yield takeEvery("CREATE_EDIT_POST", editPostWorker)
  341. }
  342. export const actionCreateEditPost= (state) =>
  343. ({
  344. type:"CREATE_EDIT_POST", state
  345. })
  346. //change subscribe
  347. function* changeSubscribeWorker({ followId, checkFollowId }) {
  348. const { myData: { aboutMe: { _id, following } } } = yield select()
  349. console.log('my following', following)
  350. console.log('check follow id', checkFollowId)
  351. console.log('my id', _id)
  352. const oldFollowing = checkFollowId ?
  353. {
  354. _id,
  355. following: [...(following||[]).filter((item) =>
  356. item._id !== followId).map(({ _id }) => ({ _id }))]
  357. }
  358. : {
  359. _id,
  360. following: [...(following||[]).map(({ _id }) =>
  361. ({ _id })), { _id: followId }]
  362. }
  363. console.log('old following', oldFollowing)
  364. console.log('еще раз май фолловинг ', following)
  365. const change = yield call(promiseWorker, actionChangeSubscribe(oldFollowing))
  366. console.log('change', change)
  367. const updateUserFollowers = yield call(promiseWorker, actionGetFollowers(followId))
  368. console.log('update user followers', updateUserFollowers)
  369. const updateMyFollowing = yield call(promiseWorker, actionGetFollowing(_id))
  370. console.log('update my following', updateMyFollowing)
  371. if (updateMyFollowing)
  372. yield put(actionChangeFollowingType(updateMyFollowing?.following))
  373. if (updateUserFollowers)
  374. yield put(actionChangeFollowersType(updateUserFollowers?.followers))
  375. }
  376. export function* changeSubscribeWatcher() {
  377. yield takeEvery("CHANGE_SUBSCRIBE", changeSubscribeWorker)
  378. }
  379. export const actionChangeSubscribeSaga= (followId,checkFollowId) =>
  380. ({
  381. type:"CHANGE_SUBSCRIBE", followId,checkFollowId
  382. })
  383. //comment
  384. export const actionAddFullCommentFeed = (postId, newResult) => ({
  385. type:"ADD_COMMENT_FEED", postId, newResult
  386. })
  387. export const actionUserUpdateTypeSaga = (user) => ({
  388. type:"USER_UPDATE", user
  389. })
  390. function* userUpdateWorker({ user }) {
  391. const {myData:{aboutMe:{_id}}}= yield select()
  392. const userUpsert = yield call(promiseWorker, actionUserUpsert(user, _id))
  393. if (userUpsert) {
  394. yield call(fullPageAboutUserWorker, { _id })
  395. yield call(fullProfilePageWorker)
  396. }
  397. }
  398. export function* userUpdateWatcher() {
  399. yield takeEvery("USER_UPDATE", userUpdateWorker)
  400. }
  401. export const actionSetAvatarTypeSaga = (file) => ({
  402. type:"SET_AVATAR", file
  403. })
  404. function* setAvatarWorker({ file }) {
  405. const {myData:{aboutMe:{_id}}}= yield select()
  406. const setAvatar = yield call(promiseWorker, actionAvatar(file, _id))
  407. console.log('setAvatar', setAvatar)
  408. const {avatar} =yield call(promiseWorker,actionGetAvatar(_id))
  409. if (setAvatar) {
  410. yield call(fullPageAboutUserWorker, { _id })
  411. yield put(actionUpdateAvatarType(avatar))
  412. // yield call(promiseWorker,actionClearPromiseForName("setAvatar"))
  413. // yield call(promiseWorker,actionClearPromiseForName("uploadFile"))
  414. }
  415. }
  416. export function* setAvatarWatcher() {
  417. yield takeEvery("SET_AVATAR", setAvatarWorker)
  418. }
  419. //clear user data after log out
  420. export const actionClearDataLogoutTypeSaga = () => ({
  421. type:"CLEAR_ALL_DATA"
  422. })
  423. function* clearAllDataWorker() {
  424. const logOut = yield put (actionAuthLogout())
  425. if (logOut) {
  426. history.push('/input')
  427. yield all([
  428. put(actionClearDataUserType()),
  429. put(actionClearFeedPostsType()),
  430. put(actionClearAboutMeType()),
  431. put(actionAllClearPromiseType())
  432. ])
  433. }
  434. }
  435. export function* clearAllDataWatcher() {
  436. yield takeEvery("CLEAR_ALL_DATA", clearAllDataWorker)
  437. }
  438. //subComment
  439. function* addSubCommentWorker({ commentId, newResult }) {
  440. yield call(promiseWorker, actionAddSubComment(commentId, newResult))
  441. console.log('newResult ', newResult)
  442. const {
  443. promise: {
  444. addSubComment: { status },
  445. },
  446. } = yield select()
  447. if (status === 'FULFILLED') {
  448. yield call(getSubCommentWorker, {commentId})
  449. }
  450. }
  451. export function* addSubCommentWatcher() {
  452. yield takeEvery("POST_SUB_COMMENT", addSubCommentWorker)
  453. }
  454. function* getSubCommentWorker({ commentId }) {
  455. const { answers } = yield call(promiseWorker,
  456. actionFindSubComment(commentId))
  457. if (answers) {
  458. yield put(actionAddSubCommentType(commentId, answers))
  459. }
  460. }
  461. export function* getSubCommentWatcher() {
  462. yield takeEvery("GET_SUB_COMMENT", getSubCommentWorker)
  463. }