Merge pull request #399 from Discours/feature/auth-resend
Some checks failed
deploy / test (push) Failing after 1m30s
deploy / Update templates on Mailgun (push) Has been skipped

Feature/auth resend
This commit is contained in:
Tony 2024-02-15 21:29:43 +03:00 committed by GitHub
commit 2cbc799219
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 2637 additions and 5330 deletions

View File

@ -1,5 +1,5 @@
{ {
"*.{js,ts,cjs,mjs,d.mts,jsx,tsx,json,jsonc,scss,css}": [ "*.{js,ts,cjs,mjs,d.mts,jsx,tsx,json,jsonc}": [
"npx @biomejs/biome check ./src && tsc" "npx @biomejs/biome check ./src && tsc"
] ]
} }

7457
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,37 +22,25 @@
"lint:code:fix": "npx @biomejs/biome lint src --apply-unsafe --log-kind=compact --verbose", "lint:code:fix": "npx @biomejs/biome lint src --apply-unsafe --log-kind=compact --verbose",
"lint:styles": "stylelint **/*.{scss,css}", "lint:styles": "stylelint **/*.{scss,css}",
"lint:styles:fix": "stylelint **/*.{scss,css} --fix", "lint:styles:fix": "stylelint **/*.{scss,css} --fix",
"pre-commit": "lint-staged",
"prepare": "husky install",
"preview": "vite preview", "preview": "vite preview",
"start": "vite", "start": "vite",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"typecheck:watch": "tsc --noEmit --watch" "typecheck:watch": "tsc --noEmit --watch"
}, },
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-js": "2.0.0",
"@solid-primitives/pagination": "0.2.10",
"cropperjs": "1.6.1",
"form-data": "4.0.0", "form-data": "4.0.0",
"ga-gtag": "1.2.0", "mailgun.js": "10.1.0"
"i18next": "22.4.15",
"i18next-icu": "2.3.0",
"idb": "7.1.1",
"intl-messageformat": "10.5.3",
"just-throttle": "4.2.0",
"mailgun.js": "8.2.1"
}, },
"devDependencies": { "devDependencies": {
"@authorizerdev/authorizer-js": "2.0.0",
"@babel/core": "7.23.3", "@babel/core": "7.23.3",
"@biomejs/biome": "^1.5.3", "@biomejs/biome": "^1.5.3",
"@graphql-codegen/cli": "5.0.0", "@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/typescript": "4.0.1", "@graphql-codegen/typescript": "^4.0.1",
"@graphql-codegen/typescript-operations": "4.0.1", "@graphql-codegen/typescript-operations": "^4.0.1",
"@graphql-codegen/typescript-urql": "4.0.0", "@graphql-codegen/typescript-urql": "^4.0.0",
"@graphql-codegen/urql-introspection": "3.0.0",
"@graphql-tools/url-loader": "8.0.1", "@graphql-tools/url-loader": "8.0.1",
"@graphql-typed-document-node/core": "3.2.0", "@hocuspocus/provider": "2.11.0",
"@hocuspocus/provider": "2.0.6",
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@nanostores/router": "0.13.0", "@nanostores/router": "0.13.0",
"@nanostores/solid": "0.4.2", "@nanostores/solid": "0.4.2",
@ -61,6 +49,7 @@
"@sentry/browser": "7.99.0", "@sentry/browser": "7.99.0",
"@solid-primitives/media": "2.2.3", "@solid-primitives/media": "2.2.3",
"@solid-primitives/memo": "1.2.4", "@solid-primitives/memo": "1.2.4",
"@solid-primitives/pagination": "0.2.10",
"@solid-primitives/share": "2.0.4", "@solid-primitives/share": "2.0.4",
"@solid-primitives/storage": "1.3.9", "@solid-primitives/storage": "1.3.9",
"@solid-primitives/upload": "0.0.110", "@solid-primitives/upload": "0.0.110",
@ -96,22 +85,25 @@
"@tiptap/extension-underline": "2.2.2", "@tiptap/extension-underline": "2.2.2",
"@tiptap/extension-youtube": "2.2.2", "@tiptap/extension-youtube": "2.2.2",
"@types/js-cookie": "3.0.6", "@types/js-cookie": "3.0.6",
"@types/node": "20.9.0", "@types/node": "^20.9.0",
"@urql/core": "4.2.3", "@urql/core": "4.2.3",
"@urql/devtools": "2.0.3", "@urql/devtools": "^2.0.3",
"babel-preset-solid": "1.8.4", "babel-preset-solid": "1.8.4",
"bootstrap": "5.3.2", "bootstrap": "5.3.2",
"change-case": "5.2.0",
"clsx": "2.0.0", "clsx": "2.0.0",
"cropperjs": "1.6.1",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"fast-deep-equal": "3.1.3", "fast-deep-equal": "3.1.3",
"ga-gtag": "1.2.0",
"graphql": "16.8.1", "graphql": "16.8.1",
"graphql-tag": "2.12.6", "graphql-tag": "2.12.6",
"husky": "8.0.3", "husky": "8.0.3",
"hygen": "6.2.11", "hygen": "6.2.11",
"i18next": "22.4.15",
"i18next-http-backend": "2.2.0", "i18next-http-backend": "2.2.0",
"i18next-icu": "2.3.0",
"intl-messageformat": "10.5.3",
"javascript-time-ago": "2.5.9", "javascript-time-ago": "2.5.9",
"jest": "29.7.0",
"js-cookie": "3.0.5", "js-cookie": "3.0.5",
"lint-staged": "15.1.0", "lint-staged": "15.1.0",
"loglevel": "1.8.1", "loglevel": "1.8.1",
@ -120,37 +112,31 @@
"prosemirror-history": "1.3.0", "prosemirror-history": "1.3.0",
"prosemirror-trailing-node": "2.0.3", "prosemirror-trailing-node": "2.0.3",
"prosemirror-view": "1.30.2", "prosemirror-view": "1.30.2",
"rollup": "3.21.6", "rollup": "4.11.0",
"sass": "1.69.5", "sass": "1.69.5",
"solid-js": "1.8.7", "solid-js": "1.8.14",
"solid-popper": "0.3.0", "solid-popper": "0.3.0",
"solid-tiptap": "0.7.0", "solid-tiptap": "0.7.0",
"solid-transition-group": "0.2.3", "solid-transition-group": "0.2.3",
"sort-json": "2.0.1", "stylelint": "^16.0.0",
"sort-package-json": "2.6.0", "stylelint-config-standard-scss": "^13.0.0",
"stylelint": "15.11.0", "stylelint-order": "^6.0.3",
"stylelint-config-standard-scss": "11.1.0", "stylelint-scss": "^6.1.0",
"stylelint-order": "6.0.3",
"stylelint-scss": "5.3.1",
"swiper": "11.0.5", "swiper": "11.0.5",
"throttle-debounce": "5.0.0", "throttle-debounce": "5.0.0",
"typescript": "5.2.2", "typescript": "5.2.2",
"typograf": "7.1.0", "typograf": "7.3.0",
"uniqolor": "1.1.0", "uniqolor": "1.1.0",
"vike": "0.4.148", "vike": "0.4.148",
"vite": "4.5.2", "vite": "5.1.2",
"vite-plugin-mkcert": "1.16.0", "vite-plugin-mkcert": "^1.17.3",
"vite-plugin-sass-dts": "1.3.11", "vite-plugin-sass-dts": "^1.3.17",
"vite-plugin-solid": "2.7.2", "vite-plugin-solid": "2.10.1",
"y-prosemirror": "1.2.1", "y-prosemirror": "1.2.2",
"yjs": "13.6.0" "yjs": "13.6.8"
}, },
"overrides": { "overrides": {
"@tiptap/extension-collaboration": { "y-prosemirror": "1.2.2",
"y-prosemirror": "1.2.1" "yjs": "13.6.8"
},
"@tiptap/extension-collaboration-cursor": {
"y-prosemirror": "1.2.1"
}
} }
} }

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"> <path d="M19.417 32c-6.792 0-9.375-5.010-9.375-8.547v-10.458h-3.219v-4.13c4.839-1.75 6.016-6.13 6.276-8.625 0.021-0.172 0.156-0.24 0.234-0.24h4.688v8.151h6.401v4.844h-6.427v9.964c0.021 1.333 0.5 3.161 2.943 3.161h0.12c0.844-0.031 1.984-0.276 2.583-0.563l1.542 4.568c-0.583 0.849-3.203 1.833-5.542 1.87h-0.24z"/> </svg>

After

Width:  |  Height:  |  Size: 403 B

View File

@ -1,8 +1,7 @@
{ {
"A guide to horizontal editorial: how an open journal works": "A guide to horizontal editorial: how an open journal works", "A guide to horizontal editorial: how an open journal works": "A guide to horizontal editorial: how an open journal works",
"About": "About",
"About the project": "About the project", "About the project": "About the project",
"Add": "Add", "About": "About",
"Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title": "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title", "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title": "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title",
"Add a link or click plus to embed media": "Add a link or click plus to embed media", "Add a link or click plus to embed media": "Add a link or click plus to embed media",
"Add an embed widget": "Add an embed widget", "Add an embed widget": "Add an embed widget",
@ -19,16 +18,17 @@
"Add signature": "Add signature", "Add signature": "Add signature",
"Add subtitle": "Add subtitle", "Add subtitle": "Add subtitle",
"Add url": "Add url", "Add url": "Add url",
"Add": "Add",
"Address on Discours": "Address on Discours", "Address on Discours": "Address on Discours",
"Album name": "Название aльбома", "Album name": "Название aльбома",
"Alignment center": "Alignment center", "Alignment center": "Alignment center",
"Alignment left": "Alignment left", "Alignment left": "Alignment left",
"Alignment right": "Alignment right", "Alignment right": "Alignment right",
"All": "All",
"All articles": "All articles", "All articles": "All articles",
"All authors": "All authors", "All authors": "All authors",
"All posts": "All posts", "All posts": "All posts",
"All topics": "All topics", "All topics": "All topics",
"All": "All",
"Almost done! Check your email.": "Almost done! Just checking your email.", "Almost done! Check your email.": "Almost done! Just checking your email.",
"Are you sure you want to delete this comment?": "Are you sure you want to delete this comment?", "Are you sure you want to delete this comment?": "Are you sure you want to delete this comment?",
"Are you sure you want to delete this draft?": "Are you sure you want to delete this draft?", "Are you sure you want to delete this draft?": "Are you sure you want to delete this draft?",
@ -40,9 +40,9 @@
"Author": "Author", "Author": "Author",
"Authors": "Authors", "Authors": "Authors",
"Autotypograph": "Autotypograph", "Autotypograph": "Autotypograph",
"Back": "Back",
"Back to editor": "Back to editor", "Back to editor": "Back to editor",
"Back to main page": "Back to main page", "Back to main page": "Back to main page",
"Back": "Back",
"Be the first to rate": "Be the first to rate", "Be the first to rate": "Be the first to rate",
"Become an author": "Become an author", "Become an author": "Become an author",
"Bold": "Bold", "Bold": "Bold",
@ -64,8 +64,8 @@
"Can make any changes, accept or reject suggestions, and share access with others": "Can make any changes, accept or reject suggestions, and share access with others", "Can make any changes, accept or reject suggestions, and share access with others": "Can make any changes, accept or reject suggestions, and share access with others",
"Can offer edits and comments, but cannot edit the post or share access with others": "Can offer edits and comments, but cannot edit the post or share access with others", "Can offer edits and comments, but cannot edit the post or share access with others": "Can offer edits and comments, but cannot edit the post or share access with others",
"Can write and edit text directly, and accept or reject suggestions from others": "Can write and edit text directly, and accept or reject suggestions from others", "Can write and edit text directly, and accept or reject suggestions from others": "Can write and edit text directly, and accept or reject suggestions from others",
"Cancel": "Cancel",
"Cancel changes": "Cancel changes", "Cancel changes": "Cancel changes",
"Cancel": "Cancel",
"Change password": "Change password", "Change password": "Change password",
"Characters": "Знаков", "Characters": "Знаков",
"Chat Title": "Chat Title", "Chat Title": "Chat Title",
@ -90,8 +90,8 @@
"Confirm": "Confirm", "Confirm": "Confirm",
"Contribute to free samizdat. Support Discours - an independent non-profit publication that works only for you. Become a pillar of the open newsroom": "Contribute to free samizdat. Support Discours - an independent non-profit publication that works only for you. Become a pillar of the open newsroom", "Contribute to free samizdat. Support Discours - an independent non-profit publication that works only for you. Become a pillar of the open newsroom": "Contribute to free samizdat. Support Discours - an independent non-profit publication that works only for you. Become a pillar of the open newsroom",
"Cooperate": "Cooperate", "Cooperate": "Cooperate",
"Copy": "Copy",
"Copy link": "Copy link", "Copy link": "Copy link",
"Copy": "Copy",
"Corrections history": "Corrections history", "Corrections history": "Corrections history",
"Create Chat": "Create Chat", "Create Chat": "Create Chat",
"Create Group": "Create a group", "Create Group": "Create a group",
@ -99,8 +99,8 @@
"Create an account to add to your bookmarks": "Create an account to add to your bookmarks", "Create an account to add to your bookmarks": "Create an account to add to your bookmarks",
"Create an account to participate in discussions": "Create an account to participate in discussions", "Create an account to participate in discussions": "Create an account to participate in discussions",
"Create an account to publish articles": "Create an account to publish articles", "Create an account to publish articles": "Create an account to publish articles",
"Create an account to subscribe": "Create an account to subscribe",
"Create an account to subscribe to new publications": "Create an account to subscribe to new publications", "Create an account to subscribe to new publications": "Create an account to subscribe to new publications",
"Create an account to subscribe": "Create an account to subscribe",
"Create an account to vote": "Create an account to vote", "Create an account to vote": "Create an account to vote",
"Create gallery": "Create gallery", "Create gallery": "Create gallery",
"Create post": "Create post", "Create post": "Create post",
@ -109,16 +109,16 @@
"Culture": "Culture", "Culture": "Culture",
"Date of Birth": "Date of Birth", "Date of Birth": "Date of Birth",
"Decline": "Decline", "Decline": "Decline",
"Delete": "Delete",
"Delete cover": "Delete cover", "Delete cover": "Delete cover",
"Delete userpic": "Delete userpic", "Delete userpic": "Delete userpic",
"Delete": "Delete",
"Description": "Description", "Description": "Description",
"Discours": "Discours",
"Discours Manifest": "Discours Manifest", "Discours Manifest": "Discours Manifest",
"Discours Partners": "Discours Partners", "Discours Partners": "Discours Partners",
"Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects": "Discours is&#160;an&#160;intellectual environment, a&#160;web space and tools that allows authors to&#160;collaborate with readers and come together to&#160;co-create publications and media projects.<br/><em>We&#160;are convinced that one voice is&#160;good, but many is&#160;better. We&#160;create the most amazing stories together</em>", "Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects": "Discours is&#160;an&#160;intellectual environment, a&#160;web space and tools that allows authors to&#160;collaborate with readers and come together to&#160;co-create publications and media projects.<br/><em>We&#160;are convinced that one voice is&#160;good, but many is&#160;better. We&#160;create the most amazing stories together</em>",
"Discours is created with our common effort": "Discours exists because of our common effort", "Discours is created with our common effort": "Discours exists because of our common effort",
"Discours an open magazine about culture, science and society": "Discours an open magazine about culture, science and society", "Discours an open magazine about culture, science and society": "Discours an open magazine about culture, science and society",
"Discours": "Discours",
"Discussing": "Discussing", "Discussing": "Discussing",
"Discussion rules": "Discussion rules", "Discussion rules": "Discussion rules",
"Discussions": "Discussions", "Discussions": "Discussions",
@ -128,12 +128,11 @@
"Drafts": "Drafts", "Drafts": "Drafts",
"Drag the image to this area": "Drag the image to this area", "Drag the image to this area": "Drag the image to this area",
"Each image must be no larger than 5 MB.": "Each image must be no larger than 5 MB.", "Each image must be no larger than 5 MB.": "Each image must be no larger than 5 MB.",
"Edit": "Edit",
"Edit profile": "Edit profile", "Edit profile": "Edit profile",
"Edit": "Edit",
"Editing": "Editing", "Editing": "Editing",
"Editor": "Editor", "Editor": "Editor",
"Email": "Mail", "Email": "Mail",
"Enter": "Enter",
"Enter URL address": "Enter URL address", "Enter URL address": "Enter URL address",
"Enter a new password": "Enter a new password", "Enter a new password": "Enter a new password",
"Enter footnote text": "Enter footnote text", "Enter footnote text": "Enter footnote text",
@ -142,26 +141,26 @@
"Enter text": "Enter text", "Enter text": "Enter text",
"Enter the code or click the link from email to confirm": "Enter the code from the email or follow the link in the email to confirm registration", "Enter the code or click the link from email to confirm": "Enter the code from the email or follow the link in the email to confirm registration",
"Enter your new password": "Enter your new password", "Enter your new password": "Enter your new password",
"Enter": "Enter",
"Error": "Error", "Error": "Error",
"Everything is ok, please give us your email address": "It's okay, just enter your email address to receive a password reset link.", "Please give us your email address": "Please provide us your email address to get the password reset link",
"Experience": "Experience", "Experience": "Experience",
"FAQ": "Tips and suggestions", "FAQ": "Tips and suggestions",
"Favorite": "Favorites",
"Favorite topics": "Favorite topics", "Favorite topics": "Favorite topics",
"Feed": "Feed", "Favorite": "Favorites",
"Feed settings": "Feed settings", "Feed settings": "Feed settings",
"Feed": "Feed",
"Feedback": "Feedback", "Feedback": "Feedback",
"Fill email": "Fill email", "Fill email": "Fill email",
"Fixed": "Fixed", "Fixed": "Fixed",
"Follow": "Follow",
"Follow the topic": "Follow the topic", "Follow the topic": "Follow the topic",
"Follow": "Follow",
"Followers": "Followers", "Followers": "Followers",
"Following": "Following", "Following": "Following",
"Forgot password?": "Forgot your password?",
"Forward": "Forward", "Forward": "Forward",
"Full name": "First and last name", "Full name": "First and last name",
"Gallery": "Gallery",
"Gallery name": "Gallery name", "Gallery name": "Gallery name",
"Gallery": "Gallery",
"Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine": "Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine", "Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine": "Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine",
"Go to main page": "Go to main page", "Go to main page": "Go to main page",
"Group Chat": "Group Chat", "Group Chat": "Group Chat",
@ -170,8 +169,8 @@
"Header 2": "Header 2", "Header 2": "Header 2",
"Header 3": "Header 3", "Header 3": "Header 3",
"Headers": "Headers", "Headers": "Headers",
"Help": "Помощь",
"Help to edit": "Help to edit", "Help to edit": "Help to edit",
"Help": "Помощь",
"Here you can customize your profile the way you want.": "Here you can customize your profile the way you want.", "Here you can customize your profile the way you want.": "Here you can customize your profile the way you want.",
"Here you can manage all your Discours subscriptions": "Here you can manage all your Discours subscriptions", "Here you can manage all your Discours subscriptions": "Here you can manage all your Discours subscriptions",
"Here you can upload your photo": "Here you can upload your photo", "Here you can upload your photo": "Here you can upload your photo",
@ -204,23 +203,23 @@
"Invalid email": "Check if your email is correct", "Invalid email": "Check if your email is correct",
"Invalid image URL": "Invalid image URL", "Invalid image URL": "Invalid image URL",
"Invalid url format": "Invalid url format", "Invalid url format": "Invalid url format",
"Invite": "Invite",
"Invite co-authors": "Invite co-authors", "Invite co-authors": "Invite co-authors",
"Invite collaborators": "Invite collaborators", "Invite collaborators": "Invite collaborators",
"Invite to collab": "Invite to Collab", "Invite to collab": "Invite to Collab",
"Invite": "Invite",
"It does not look like url": "It doesn't look like a link", "It does not look like url": "It doesn't look like a link",
"Italic": "Italic", "Italic": "Italic",
"Join": "Join",
"Join our maillist": "To receive the best postings, just enter your email", "Join our maillist": "To receive the best postings, just enter your email",
"Join the community": "Join the community", "Join the community": "Join the community",
"Join the global community of authors!": "Join the global community of authors from all over the world!", "Join the global community of authors!": "Join the global community of authors from all over the world!",
"Join": "Join",
"Just start typing...": "Just start typing...", "Just start typing...": "Just start typing...",
"Knowledge base": "Knowledge base", "Knowledge base": "Knowledge base",
"Language": "Language", "Language": "Language",
"Last rev.": "Посл. изм.", "Last rev.": "Посл. изм.",
"Let's log in": "Let's log in", "Let's log in": "Let's log in",
"Link copied": "Link copied",
"Link copied to clipboard": "Link copied to clipboard", "Link copied to clipboard": "Link copied to clipboard",
"Link copied": "Link copied",
"Link sent, check your email": "Link sent, check your email", "Link sent, check your email": "Link sent, check your email",
"List of authors of the open editorial community": "List of authors of the open editorial community", "List of authors of the open editorial community": "List of authors of the open editorial community",
"Lists": "Lists", "Lists": "Lists",
@ -263,12 +262,12 @@
"Participating": "Participating", "Participating": "Participating",
"Participation": "Participation", "Participation": "Participation",
"Partners": "Partners", "Partners": "Partners",
"Password": "Password",
"Password again": "Password again", "Password again": "Password again",
"Password should be at least 8 characters": "Password should be at least 8 characters", "Password should be at least 8 characters": "Password should be at least 8 characters",
"Password should contain at least one number": "Password should contain at least one number", "Password should contain at least one number": "Password should contain at least one number",
"Password should contain at least one special character: !@#$%^&*": "Password should contain at least one special character: !@#$%^&*", "Password should contain at least one special character: !@#$%^&*": "Password should contain at least one special character: !@#$%^&*",
"Password updated!": "Password updated!", "Password updated!": "Password updated!",
"Password": "Password",
"Passwords are not equal": "Passwords are not equal", "Passwords are not equal": "Passwords are not equal",
"Paste Embed code": "Paste Embed code", "Paste Embed code": "Paste Embed code",
"Personal": "Personal", "Personal": "Personal",
@ -278,18 +277,18 @@
"Please confirm your email to finish": "Confirm your email and the action will complete", "Please confirm your email to finish": "Confirm your email and the action will complete",
"Please enter a name to sign your comments and publication": "Please enter a name to sign your comments and publication", "Please enter a name to sign your comments and publication": "Please enter a name to sign your comments and publication",
"Please enter email": "Please enter your email", "Please enter email": "Please enter your email",
"Please enter password": "Please enter a password",
"Please enter password again": "Please enter password again", "Please enter password again": "Please enter password again",
"Please enter password": "Please enter a password",
"Please, confirm email": "Please confirm email", "Please, confirm email": "Please confirm email",
"Please, set the main topic first": "Please, set the main topic first", "Please, set the main topic first": "Please, set the main topic first",
"Podcasts": "Podcasts", "Podcasts": "Podcasts",
"Poetry": "Poetry", "Poetry": "Poetry",
"Popular": "Popular",
"Popular authors": "Popular authors", "Popular authors": "Popular authors",
"Popular": "Popular",
"Principles": "Community principles", "Principles": "Community principles",
"Professional principles that the open editorial team follows in its work": "Professional principles that the open editorial team follows in its work", "Professional principles that the open editorial team follows in its work": "Professional principles that the open editorial team follows in its work",
"Profile": "Profile",
"Profile settings": "Profile settings", "Profile settings": "Profile settings",
"Profile": "Profile",
"Publications": "Publications", "Publications": "Publications",
"PublicationsWithCount": "{count, plural, =0 {no publications} one {{count} publication} other {{count} publications}}", "PublicationsWithCount": "{count, plural, =0 {no publications} one {{count} publication} other {{count} publications}}",
"Publish Album": "Publish Album", "Publish Album": "Publish Album",
@ -308,28 +307,28 @@
"Reports": "Reports", "Reports": "Reports",
"Required": "Required", "Required": "Required",
"Resend code": "Send confirmation", "Resend code": "Send confirmation",
"Restore password": "Restore password",
"Rules of the journal Discours": "Rules of the journal Discours", "Rules of the journal Discours": "Rules of the journal Discours",
"Save draft": "Save draft", "Save draft": "Save draft",
"Save settings": "Save settings", "Save settings": "Save settings",
"Saving...": "Saving...", "Saving...": "Saving...",
"Scroll up": "Scroll up", "Scroll up": "Scroll up",
"Search": "Search",
"Search author": "Search author", "Search author": "Search author",
"Search topic": "Search topic", "Search topic": "Search topic",
"Search": "Search",
"Sections": "Sections", "Sections": "Sections",
"Security": "Security", "Security": "Security",
"Select": "Select", "Select": "Select",
"Self-publishing exists thanks to the help of wonderful people from all over the world. Thank you!": "Samizdat exists thanks to the help of wonderful people from all over the world. Thank you!", "Self-publishing exists thanks to the help of wonderful people from all over the world. Thank you!": "Samizdat exists thanks to the help of wonderful people from all over the world. Thank you!",
"Send": "Send",
"Send link again": "Send link again", "Send link again": "Send link again",
"Send": "Send",
"Set the new password": "Set the new password",
"Settings": "Settings", "Settings": "Settings",
"Share": "Share",
"Share publication": "Share publication", "Share publication": "Share publication",
"Show": "Show", "Share": "Share",
"Show lyrics": "Show lyrics", "Show lyrics": "Show lyrics",
"Show more": "Show more", "Show more": "Show more",
"Show table of contents": "Show table of contents", "Show table of contents": "Show table of contents",
"Show": "Show",
"Site search": "Site search", "Site search": "Site search",
"Slug": "Slug", "Slug": "Slug",
"Social networks": "Social networks", "Social networks": "Social networks",
@ -348,11 +347,11 @@
"Start conversation": "Start a conversation", "Start conversation": "Start a conversation",
"Start dialog": "Start dialog", "Start dialog": "Start dialog",
"Subsccriptions": "Subscriptions", "Subsccriptions": "Subscriptions",
"Subscribe": "Subscribe",
"Subscribe to the best publications newsletter": "Subscribe to the best publications newsletter", "Subscribe to the best publications newsletter": "Subscribe to the best publications newsletter",
"Subscribe us": "Subscribe us", "Subscribe us": "Subscribe us",
"Subscribe what you like to tune your personal feed": "Subscribe to topics that interest you to customize your personal feed and get instant updates on new posts and discussions", "Subscribe what you like to tune your personal feed": "Subscribe to topics that interest you to customize your personal feed and get instant updates on new posts and discussions",
"Subscribe who you like to tune your personal feed": "Subscribe to authors you're interested in to customize your personal feed and get instant updates on new posts and discussions", "Subscribe who you like to tune your personal feed": "Subscribe to authors you're interested in to customize your personal feed and get instant updates on new posts and discussions",
"Subscribe": "Subscribe",
"SubscriberWithCount": "{count, plural, =0 {no followers} one {{count} follower} other {{count} followers}}", "SubscriberWithCount": "{count, plural, =0 {no followers} one {{count} follower} other {{count} followers}}",
"Subscription": "Subscription", "Subscription": "Subscription",
"SubscriptionWithCount": "{count, plural, =0 {no subscriptions} one {{count} subscription} other {{count} subscriptions}}", "SubscriptionWithCount": "{count, plural, =0 {no subscriptions} one {{count} subscription} other {{count} subscriptions}}",
@ -366,8 +365,8 @@
"Support us": "Support us", "Support us": "Support us",
"Terms of use": "Site rules", "Terms of use": "Site rules",
"Text checking": "Text checking", "Text checking": "Text checking",
"Thank you": "Thank you",
"Thank you!": "Thank you!", "Thank you!": "Thank you!",
"Thank you": "Thank you",
"The address is already taken": "The address is already taken", "The address is already taken": "The address is already taken",
"The most interesting publications on the topic": "The most interesting publications on the topic {topicName}", "The most interesting publications on the topic": "The most interesting publications on the topic {topicName}",
"Thematic table of contents of the magazine. Here you can find all the topics that community authors have written about.": "Thematic table of contents of the magazine. Here you can find all the topics that community authors have written about.", "Thematic table of contents of the magazine. Here you can find all the topics that community authors have written about.": "Thematic table of contents of the magazine. Here you can find all the topics that community authors have written about.",
@ -378,7 +377,10 @@
"There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?", "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?",
"There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?", "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?",
"This comment has not yet been rated": "This comment has not yet been rated", "This comment has not yet been rated": "This comment has not yet been rated",
"This email is already taken. If it's you": "This email is already taken. If it's you", "This email is": "This email is",
"This email is not verified": "This email is not verified",
"This email is verified": "This email is verified",
"This email is registered": "This email is registered",
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "This functionality is currently not available, we would like to work on this issue. Use the download link.", "This functionality is currently not available, we would like to work on this issue. Use the download link.": "This functionality is currently not available, we would like to work on this issue. Use the download link.",
"This month": "This month", "This month": "This month",
"This post has not been rated yet": "This post has not been rated yet", "This post has not been rated yet": "This post has not been rated yet",
@ -398,36 +400,35 @@
"Top topics": "Interesting topics", "Top topics": "Interesting topics",
"Top viewed": "Most viewed", "Top viewed": "Most viewed",
"Topic is supported by": "Topic is supported by", "Topic is supported by": "Topic is supported by",
"Topics": "Topics",
"Topics which supported by author": "Topics which supported by author", "Topics which supported by author": "Topics which supported by author",
"Topics": "Topics",
"Try to find another way": "Try to find another way", "Try to find another way": "Try to find another way",
"Unfollow": "Unfollow",
"Unfollow the topic": "Unfollow the topic", "Unfollow the topic": "Unfollow the topic",
"Unfollow": "Unfollow",
"Unnamed draft": "Unnamed draft", "Unnamed draft": "Unnamed draft",
"Upload": "Upload",
"Upload error": "Upload error", "Upload error": "Upload error",
"Upload userpic": "Upload userpic", "Upload userpic": "Upload userpic",
"Upload video": "Upload video", "Upload video": "Upload video",
"Upload": "Upload",
"Uploading image": "Uploading image", "Uploading image": "Uploading image",
"User with this email already exists": "User with this email already exists",
"Username": "Username", "Username": "Username",
"Userpic": "Userpic", "Userpic": "Userpic",
"Users": "Users", "Users": "Users",
"Video": "Video",
"Video format not supported": "Video format not supported", "Video format not supported": "Video format not supported",
"Video": "Video",
"Views": "Views", "Views": "Views",
"We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues": "We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues", "We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues": "We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues",
"We can't find you, check email or": "We can't find you, check email or", "We can't find you, check email or": "We can't find you, check email or",
"We couldn't find anything for your request": "We&nbsp;couldn&rsquo;t find anything for your request", "We couldn't find anything for your request": "We&nbsp;couldn&rsquo;t find anything for your request",
"We know you, please try to login": "This email address is already registered, please try to login", "We know you, please try to login": "This email address is already registered, please try to login",
"We've sent you a message with a link to enter our website.": "We've sent you an email with a link to your email. Follow the link in the email to enter our website.", "We've sent you a message with a link to enter our website.": "We've sent you an email with a link to your email. Follow the link in the email to enter our website.",
"Welcome to Discours": "Welcome to Discours",
"Welcome to Discours to add to your bookmarks": "Welcome to Discours to add to your bookmarks", "Welcome to Discours to add to your bookmarks": "Welcome to Discours to add to your bookmarks",
"Welcome to Discours to participate in discussions": "Welcome to Discours to participate in discussions", "Welcome to Discours to participate in discussions": "Welcome to Discours to participate in discussions",
"Welcome to Discours to publish articles": "Welcome to Discours to publish articles", "Welcome to Discours to publish articles": "Welcome to Discours to publish articles",
"Welcome to Discours to subscribe": "Welcome to Discours to subscribe",
"Welcome to Discours to subscribe to new publications": "Welcome to Discours to subscribe to new publications", "Welcome to Discours to subscribe to new publications": "Welcome to Discours to subscribe to new publications",
"Welcome to Discours to subscribe": "Welcome to Discours to subscribe",
"Welcome to Discours to vote": "Welcome to Discours to vote", "Welcome to Discours to vote": "Welcome to Discours to vote",
"Welcome to Discours": "Welcome to Discours",
"Where": "From", "Where": "From",
"Why you can earn a hole in your karma and how to receive rays of gratitude for your contribution to discussions in samizdat communities": "Why you can earn a hole in your karma and how to receive rays of gratitude for your contribution to discussions in samizdat communities", "Why you can earn a hole in your karma and how to receive rays of gratitude for your contribution to discussions in samizdat communities": "Why you can earn a hole in your karma and how to receive rays of gratitude for your contribution to discussions in samizdat communities",
"Words": "Слов", "Words": "Слов",
@ -440,6 +441,7 @@
"Write good articles, comment\nand it won't be so empty here": "Write good articles, comment\nand it won't be so empty here", "Write good articles, comment\nand it won't be so empty here": "Write good articles, comment\nand it won't be so empty here",
"Write message": "Write a message", "Write message": "Write a message",
"Write to us": "Write to us", "Write to us": "Write to us",
"You can": "You can",
"Write your colleagues name or email": "Write your colleague's name or email", "Write your colleagues name or email": "Write your colleague's name or email",
"You can download multiple tracks at once in .mp3, .wav or .flac formats": "You can download multiple tracks at once in .mp3, .wav or .flac formats", "You can download multiple tracks at once in .mp3, .wav or .flac formats": "You can download multiple tracks at once in .mp3, .wav or .flac formats",
"You can now login using your new password": "Теперь вы можете входить с помощью нового пароля", "You can now login using your new password": "Теперь вы можете входить с помощью нового пароля",
@ -489,13 +491,16 @@
"min. 1400×1400 pix": "мин. 1400×1400 пикс.", "min. 1400×1400 pix": "мин. 1400×1400 пикс.",
"music": "music", "music": "music",
"my feed": "my ribbon", "my feed": "my ribbon",
"not verified": "not verified",
"number list": "number list", "number list": "number list",
"or sign in with social networks": "or sign in with social networks", "or sign in with social networks": "or sign in with social networks",
"personal data usage and email notifications": "to process personal data and receive email notifications", "personal data usage and email notifications": "to process personal data and receive email notifications",
"post": "post", "post": "post",
"principles keywords": "Discours.io, communities, values, editorial rules, polyphony, creation", "principles keywords": "Discours.io, communities, values, editorial rules, polyphony, creation",
"register": "register", "register": "register",
"registered": "registered",
"repeat": "repeat", "repeat": "repeat",
"resend confirmation link": "resend confirmation link",
"shout": "post", "shout": "post",
"shoutsWithCount": "{count} {count, plural, one {post} other {posts}}", "shoutsWithCount": "{count} {count, plural, one {post} other {posts}}",
"sign up or sign in": "sign up or sign in", "sign up or sign in": "sign up or sign in",
@ -507,12 +512,13 @@
"subscription": "subscription", "subscription": "subscription",
"subscription_rp": "subscription", "subscription_rp": "subscription",
"subscriptions": "subscriptions", "subscriptions": "subscriptions",
"terms of use": "terms of use",
"terms of use keywords": "Discours.io, site rules, terms of use", "terms of use keywords": "Discours.io, site rules, terms of use",
"terms of use": "terms of use",
"today": "today", "today": "today",
"topicKeywords": "{topic}, Discours.io, articles, journalism, research", "topicKeywords": "{topic}, Discours.io, articles, journalism, research",
"topics": "topics", "topics": "topics",
"user already exist": "user already exists", "user already exist": "user already exists",
"verified": "verified",
"video": "video", "video": "video",
"view": "view", "view": "view",
"viewsWithCount": "{count} {count, plural, one {view} other {views}}", "viewsWithCount": "{count} {count, plural, one {view} other {views}}",

View File

@ -1,9 +1,8 @@
{ {
"A guide to horizontal editorial: how an open journal works": "Гид по горизонтальной редакции: как работает открытый журнал", "A guide to horizontal editorial: how an open journal works": "Гид по горизонтальной редакции: как работает открытый журнал",
"A short introduction to keep the reader interested": "Добавьте вступление, чтобы заинтересовать читателя", "A short introduction to keep the reader interested": "Добавьте вступление, чтобы заинтересовать читателя",
"About": "О себе",
"About the project": "О проекте", "About the project": "О проекте",
"Add": "Добавить", "About": "О себе",
"Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title": "Добавьте несколько тем, чтобы читатель знал, о чем ваш материал, и мог найти его на страницах интересных ему тем. Темы можно менять местами, первая тема становится заглавной", "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title": "Добавьте несколько тем, чтобы читатель знал, о чем ваш материал, и мог найти его на страницах интересных ему тем. Темы можно менять местами, первая тема становится заглавной",
"Add a link or click plus to embed media": "Добавьте ссылку или нажмите плюс для вставки медиа", "Add a link or click plus to embed media": "Добавьте ссылку или нажмите плюс для вставки медиа",
"Add an embed widget": "Добавить embed-виджет", "Add an embed widget": "Добавить embed-виджет",
@ -21,17 +20,18 @@
"Add subtitle": "Добавить подзаголовок", "Add subtitle": "Добавить подзаголовок",
"Add to bookmarks": "Добавить в закладки", "Add to bookmarks": "Добавить в закладки",
"Add url": "Добавить ссылку", "Add url": "Добавить ссылку",
"Add": "Добавить",
"Address on Discours": "Адрес на Дискурсе", "Address on Discours": "Адрес на Дискурсе",
"Album name": "Название альбома", "Album name": "Название альбома",
"Alignment center": "По центру", "Alignment center": "По центру",
"Alignment left": "По левому краю", "Alignment left": "По левому краю",
"Alignment right": "По правому краю", "Alignment right": "По правому краю",
"All": "Все",
"All articles": "Все материалы", "All articles": "Все материалы",
"All authors": "Все авторы", "All authors": "Все авторы",
"All posts": "Все публикации",
"All posts rating": "Рейтинг всех постов", "All posts rating": "Рейтинг всех постов",
"All posts": "Все публикации",
"All topics": "Все темы", "All topics": "Все темы",
"All": "Все",
"Almost done! Check your email.": "Почти готово! Осталось подтвердить вашу почту.", "Almost done! Check your email.": "Почти готово! Осталось подтвердить вашу почту.",
"Are you sure you want to delete this comment?": "Уверены, что хотите удалить этот комментарий?", "Are you sure you want to delete this comment?": "Уверены, что хотите удалить этот комментарий?",
"Are you sure you want to delete this draft?": "Уверены, что хотите удалить этот черновик?", "Are you sure you want to delete this draft?": "Уверены, что хотите удалить этот черновик?",
@ -44,9 +44,9 @@
"Author": "Автор", "Author": "Автор",
"Authors": "Авторы", "Authors": "Авторы",
"Autotypograph": "Автотипограф", "Autotypograph": "Автотипограф",
"Back": "Назад",
"Back to editor": "Вернуться в редактор", "Back to editor": "Вернуться в редактор",
"Back to main page": "Вернуться на главную", "Back to main page": "Вернуться на главную",
"Back": "Назад",
"Be the first to rate": "Оцените первым", "Be the first to rate": "Оцените первым",
"Become an author": "Стать автором", "Become an author": "Стать автором",
"Bold": "Жирный", "Bold": "Жирный",
@ -68,8 +68,8 @@
"Can make any changes, accept or reject suggestions, and share access with others": "Может вносить любые изменения, принимать и отклонять предложения, а также делиться доступом с другими", "Can make any changes, accept or reject suggestions, and share access with others": "Может вносить любые изменения, принимать и отклонять предложения, а также делиться доступом с другими",
"Can offer edits and comments, but cannot edit the post or share access with others": "Может предлагать правки и комментарии, но не может изменять пост и делиться доступом с другими", "Can offer edits and comments, but cannot edit the post or share access with others": "Может предлагать правки и комментарии, но не может изменять пост и делиться доступом с другими",
"Can write and edit text directly, and accept or reject suggestions from others": "Может писать и редактировать текст напрямую, а также принимать или отклонять предложения других", "Can write and edit text directly, and accept or reject suggestions from others": "Может писать и редактировать текст напрямую, а также принимать или отклонять предложения других",
"Cancel": "Отмена",
"Cancel changes": "Отменить изменения", "Cancel changes": "Отменить изменения",
"Cancel": "Отмена",
"Change password": "Сменить пароль", "Change password": "Сменить пароль",
"Characters": "Знаков", "Characters": "Знаков",
"Chat Title": "Тема дискурса", "Chat Title": "Тема дискурса",
@ -84,8 +84,8 @@
"Come up with a subtitle for your story": "Придумайте подзаголовок вашей истории", "Come up with a subtitle for your story": "Придумайте подзаголовок вашей истории",
"Come up with a title for your story": "Придумайте заголовок вашей истории", "Come up with a title for your story": "Придумайте заголовок вашей истории",
"Coming soon": "Уже скоро", "Coming soon": "Уже скоро",
"Comment": "Комментировать",
"Comment successfully deleted": "Комментарий успешно удален", "Comment successfully deleted": "Комментарий успешно удален",
"Comment": "Комментировать",
"Commentator": "Комментатор", "Commentator": "Комментатор",
"Comments": "Комментарии", "Comments": "Комментарии",
"Communities": "Сообщества", "Communities": "Сообщества",
@ -95,8 +95,8 @@
"Confirm": "Подтвердить", "Confirm": "Подтвердить",
"Contribute to free samizdat. Support Discours - an independent non-profit publication that works only for you. Become a pillar of the open newsroom": "Внесите вклад в свободный самиздат. Поддержите Дискурс — независимое некоммерческое издание, которое работает только для вас. Станьте опорой открытой редакции", "Contribute to free samizdat. Support Discours - an independent non-profit publication that works only for you. Become a pillar of the open newsroom": "Внесите вклад в свободный самиздат. Поддержите Дискурс — независимое некоммерческое издание, которое работает только для вас. Станьте опорой открытой редакции",
"Cooperate": "Соучаствовать", "Cooperate": "Соучаствовать",
"Copy": "Скопировать",
"Copy link": "Скопировать ссылку", "Copy link": "Скопировать ссылку",
"Copy": "Скопировать",
"Corrections history": "История правок", "Corrections history": "История правок",
"Create Chat": "Создать чат", "Create Chat": "Создать чат",
"Create Group": "Создать группу", "Create Group": "Создать группу",
@ -104,8 +104,8 @@
"Create an account to add to your bookmarks": "Создайте аккаунт, чтобы добавить в закладки", "Create an account to add to your bookmarks": "Создайте аккаунт, чтобы добавить в закладки",
"Create an account to participate in discussions": "Создайте аккаунт для участия в дискуссиях", "Create an account to participate in discussions": "Создайте аккаунт для участия в дискуссиях",
"Create an account to publish articles": "Создайте аккаунт, чтобы публиковать статьи", "Create an account to publish articles": "Создайте аккаунт, чтобы публиковать статьи",
"Create an account to subscribe": "Создайте аккаунт, чтобы подписаться",
"Create an account to subscribe to new publications": "Создайте аккаунт для подписки на новые публикации", "Create an account to subscribe to new publications": "Создайте аккаунт для подписки на новые публикации",
"Create an account to subscribe": "Создайте аккаунт, чтобы подписаться",
"Create an account to vote": "Создайте аккаунт, чтобы голосовать", "Create an account to vote": "Создайте аккаунт, чтобы голосовать",
"Create gallery": "Создать галерею", "Create gallery": "Создать галерею",
"Create post": "Создать публикацию", "Create post": "Создать публикацию",
@ -114,16 +114,16 @@
"Culture": "Культура", "Culture": "Культура",
"Date of Birth": "Дата рождения", "Date of Birth": "Дата рождения",
"Decline": "Отмена", "Decline": "Отмена",
"Delete": "Удалить",
"Delete cover": "Удалить обложку", "Delete cover": "Удалить обложку",
"Delete userpic": "Удалить аватар", "Delete userpic": "Удалить аватар",
"Delete": "Удалить",
"Description": "Описание", "Description": "Описание",
"Discours": "Дискурс",
"Discours Manifest": "Манифест Дискурса", "Discours Manifest": "Манифест Дискурса",
"Discours Partners": "Партнеры Дискурса", "Discours Partners": "Партнеры Дискурса",
"Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects": "Дискурс&#160;&#8212; это интеллектуальная среда, веб-пространство и&#160;инструменты, которые позволяют авторам сотрудничать&#160;с&#160;читателями и&#160;объединяться для совместного создания публикаций и&#160;медиапроектов.<br/>Мы&#160;убеждены, один голос хорошо, а&#160;много&#160;&#8212; лучше. Самые потрясающиe истории мы создаём вместе.", "Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects": "Дискурс&#160;&#8212; это интеллектуальная среда, веб-пространство и&#160;инструменты, которые позволяют авторам сотрудничать&#160;с&#160;читателями и&#160;объединяться для совместного создания публикаций и&#160;медиапроектов.<br/>Мы&#160;убеждены, один голос хорошо, а&#160;много&#160;&#8212; лучше. Самые потрясающиe истории мы создаём вместе.",
"Discours is created with our common effort": "Дискурс существует благодаря нашему общему вкладу", "Discours is created with our common effort": "Дискурс существует благодаря нашему общему вкладу",
"Discours an open magazine about culture, science and society": "Дискурс открытый журнал о культуре, науке и обществе", "Discours an open magazine about culture, science and society": "Дискурс открытый журнал о культуре, науке и обществе",
"Discours": "Дискурс",
"Discours_theme": "Тема дискурса", "Discours_theme": "Тема дискурса",
"Discussing": "Обсуждаемое", "Discussing": "Обсуждаемое",
"Discussion rules": "Правила дискуссий", "Discussion rules": "Правила дискуссий",
@ -134,13 +134,12 @@
"Drafts": "Черновики", "Drafts": "Черновики",
"Drag the image to this area": "Перетащите изображение в эту область", "Drag the image to this area": "Перетащите изображение в эту область",
"Each image must be no larger than 5 MB.": "Каждое изображение должно быть размером не больше 5 мб.", "Each image must be no larger than 5 MB.": "Каждое изображение должно быть размером не больше 5 мб.",
"Edit": "Редактировать",
"Edit profile": "Редактировать профиль", "Edit profile": "Редактировать профиль",
"Edit": "Редактировать",
"Edited": "Отредактирован", "Edited": "Отредактирован",
"Editing": "Редактирование", "Editing": "Редактирование",
"Editor": "Редактор", "Editor": "Редактор",
"Email": "Почта", "Email": "Почта",
"Enter": "Войти",
"Enter URL address": "Введите адрес ссылки", "Enter URL address": "Введите адрес ссылки",
"Enter a new password": "Введите новый пароль", "Enter a new password": "Введите новый пароль",
"Enter footnote text": "Введите текст сноски", "Enter footnote text": "Введите текст сноски",
@ -149,39 +148,39 @@
"Enter text": "Введите текст", "Enter text": "Введите текст",
"Enter the code or click the link from email to confirm": "Введите код из письма или пройдите по ссылке в письме для подтверждения регистрации", "Enter the code or click the link from email to confirm": "Введите код из письма или пройдите по ссылке в письме для подтверждения регистрации",
"Enter your new password": "Введите новый пароль", "Enter your new password": "Введите новый пароль",
"Enter": "Войти",
"Error": "Ошибка", "Error": "Ошибка",
"Everything is ok, please give us your email address": "Ничего страшного, просто укажите свою почту, чтобы получить ссылку для сброса пароля.", "Please give us your email address": "Пожалуйста, укажите свою почту, чтобы получить ссылку для сброса пароля",
"Experience": "Личный опыт", "Experience": "Личный опыт",
"FAQ": "Советы и предложения", "FAQ": "Советы и предложения",
"Favorite": "Избранное",
"Favorite topics": "Избранные темы", "Favorite topics": "Избранные темы",
"Feed": "Лента", "Favorite": "Избранное",
"Feed settings": "Настройки ленты", "Feed settings": "Настройки ленты",
"Feed": "Лента",
"Feedback": "Обратная связь", "Feedback": "Обратная связь",
"Fill email": "Введите почту", "Fill email": "Введите почту",
"Fixed": "Все поправлено", "Fixed": "Все поправлено",
"Follow": "Подписаться",
"Follow the topic": "Подписаться на тему", "Follow the topic": "Подписаться на тему",
"Follow": "Подписаться",
"Followers": "Подписчики", "Followers": "Подписчики",
"Following": "Вы подписаны", "Following": "Вы подписаны",
"Forgot password?": "Забыли пароль?",
"Forward": "Переслать", "Forward": "Переслать",
"Full name": "Имя и фамилия", "Full name": "Имя и фамилия",
"Gallery": "Галерея",
"Gallery name": "Название галереи", "Gallery name": "Название галереи",
"Gallery": "Галерея",
"Genre...": "Жанр...", "Genre...": "Жанр...",
"Get notifications": "Получать уведомления", "Get notifications": "Получать уведомления",
"Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine": "Познакомитесь с выдающимися людьми нашего времени, участвуйте в редактировании и обсуждении статей, выступайте экспертом, оценивайте материалы других авторов со всего мира и определяйте, какие статьи будут опубликованы в журнале", "Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine": "Познакомитесь с выдающимися людьми нашего времени, участвуйте в редактировании и обсуждении статей, выступайте экспертом, оценивайте материалы других авторов со всего мира и определяйте, какие статьи будут опубликованы в журнале",
"Go to main page": "Перейти на главную", "Go to main page": "Перейти на главную",
"Group Chat": "Общий чат", "Group Chat": "Общий чат",
"Groups": "Группы", "Groups": "Группы",
"Header": "Заголовок",
"Header 1": "Заголовок 1", "Header 1": "Заголовок 1",
"Header 2": "Заголовок 2", "Header 2": "Заголовок 2",
"Header 3": "Заголовок 3", "Header 3": "Заголовок 3",
"Header": "Заголовок",
"Headers": "Заголовки", "Headers": "Заголовки",
"Help": "Помощь",
"Help to edit": "Помочь редактировать", "Help to edit": "Помочь редактировать",
"Help": "Помощь",
"Here you can customize your profile the way you want.": "Здесь можно настроить свой профиль так, как вы хотите.", "Here you can customize your profile the way you want.": "Здесь можно настроить свой профиль так, как вы хотите.",
"Here you can manage all your Discours subscriptions": "Здесь можно управлять всеми своими подписками на Дискурсе", "Here you can manage all your Discours subscriptions": "Здесь можно управлять всеми своими подписками на Дискурсе",
"Here you can upload your photo": "Здесь вы можете загрузить свою фотографию", "Here you can upload your photo": "Здесь вы можете загрузить свою фотографию",
@ -214,25 +213,25 @@
"Invalid email": "Проверьте правильность ввода почты", "Invalid email": "Проверьте правильность ввода почты",
"Invalid image URL": "Некорректная ссылка на изображение", "Invalid image URL": "Некорректная ссылка на изображение",
"Invalid url format": "Неверный формат ссылки", "Invalid url format": "Неверный формат ссылки",
"Invite": "Пригласить",
"Invite co-authors": "Пригласить соавторов", "Invite co-authors": "Пригласить соавторов",
"Invite collaborators": "Пригласить соавторов", "Invite collaborators": "Пригласить соавторов",
"Invite experts": "Пригласить экспертов", "Invite experts": "Пригласить экспертов",
"Invite to collab": "Пригласить к участию", "Invite to collab": "Пригласить к участию",
"Invite": "Пригласить",
"It does not look like url": "Это не похоже на ссылку", "It does not look like url": "Это не похоже на ссылку",
"Italic": "Курсив", "Italic": "Курсив",
"Join": "Присоединиться",
"Join our maillist": "Чтобы получать рассылку лучших публикаций, просто укажите свою почту", "Join our maillist": "Чтобы получать рассылку лучших публикаций, просто укажите свою почту",
"Join the community": "Присоединиться к сообществу", "Join the community": "Присоединиться к сообществу",
"Join the global community of authors!": "Присоединятесь к глобальному сообществу авторов со всего мира!", "Join the global community of authors!": "Присоединятесь к глобальному сообществу авторов со всего мира!",
"Join": "Присоединиться",
"Just start typing...": "Просто начните печатать...", "Just start typing...": "Просто начните печатать...",
"Karma": "Карма", "Karma": "Карма",
"Knowledge base": "База знаний", "Knowledge base": "База знаний",
"Language": "Язык", "Language": "Язык",
"Last rev.": "Посл. изм.", "Last rev.": "Посл. изм.",
"Let's log in": "Давайте авторизуемся", "Let's log in": "Давайте авторизуемся",
"Link copied": "Ссылка скопирована",
"Link copied to clipboard": "Ссылка скопирована в буфер обмена", "Link copied to clipboard": "Ссылка скопирована в буфер обмена",
"Link copied": "Ссылка скопирована",
"Link sent, check your email": "Ссылка отправлена, проверьте почту", "Link sent, check your email": "Ссылка отправлена, проверьте почту",
"List of authors of the open editorial community": "Список авторов сообщества открытой редакции", "List of authors of the open editorial community": "Список авторов сообщества открытой редакции",
"Lists": "Списки", "Lists": "Списки",
@ -276,12 +275,12 @@
"Participating": "Участвовать", "Participating": "Участвовать",
"Participation": "Соучастие", "Participation": "Соучастие",
"Partners": "Партнёры", "Partners": "Партнёры",
"Password": "Пароль",
"Password again": "Пароль ещё раз", "Password again": "Пароль ещё раз",
"Password should be at least 8 characters": "Пароль должен быть не менее 8 символов", "Password should be at least 8 characters": "Пароль должен быть не менее 8 символов",
"Password should contain at least one number": "Пароль должен содержать хотя бы одну цифру", "Password should contain at least one number": "Пароль должен содержать хотя бы одну цифру",
"Password should contain at least one special character: !@#$%^&*": "Пароль должен содержать хотя бы один спецсимвол: !@#$%^&*", "Password should contain at least one special character: !@#$%^&*": "Пароль должен содержать хотя бы один спецсимвол: !@#$%^&*",
"Password updated!": "Пароль обновлен!", "Password updated!": "Пароль обновлен!",
"Password": "Пароль",
"Passwords are not equal": "Пароли не совпадают", "Passwords are not equal": "Пароли не совпадают",
"Paste Embed code": "Вставьте embed код", "Paste Embed code": "Вставьте embed код",
"Personal": "Личные", "Personal": "Личные",
@ -292,27 +291,27 @@
"Please confirm your email to finish": "Подтвердите почту и действие совершится", "Please confirm your email to finish": "Подтвердите почту и действие совершится",
"Please enter a name to sign your comments and publication": "Пожалуйста, введите имя, которое будет отображаться на сайте", "Please enter a name to sign your comments and publication": "Пожалуйста, введите имя, которое будет отображаться на сайте",
"Please enter email": "Пожалуйста, введите почту", "Please enter email": "Пожалуйста, введите почту",
"Please enter password": "Пожалуйста, введите пароль",
"Please enter password again": "Пожалуйста, введите пароль ещё рез", "Please enter password again": "Пожалуйста, введите пароль ещё рез",
"Please enter password": "Пожалуйста, введите пароль",
"Please, confirm email": "Пожалуйста, подтвердите электронную почту", "Please, confirm email": "Пожалуйста, подтвердите электронную почту",
"Please, set the main topic first": "Пожалуйста, сначала выберите главную тему", "Please, set the main topic first": "Пожалуйста, сначала выберите главную тему",
"Please, set the article title": "Пожалуйста, задайте заголовок статьи", "Please, set the article title": "Пожалуйста, задайте заголовок статьи",
"Podcasts": "Подкасты", "Podcasts": "Подкасты",
"Poetry": "Поэзия", "Poetry": "Поэзия",
"Popular": "Популярное",
"Popular authors": "Популярные авторы", "Popular authors": "Популярные авторы",
"Popular": "Популярное",
"Preview": "Предпросмотр", "Preview": "Предпросмотр",
"Principles": "Принципы сообщества", "Principles": "Принципы сообщества",
"Professional principles that the open editorial team follows in its work": "Профессиональные принципы, которым открытая редакция следует в работе", "Professional principles that the open editorial team follows in its work": "Профессиональные принципы, которым открытая редакция следует в работе",
"Profile": "Профиль",
"Profile settings": "Настройки профиля", "Profile settings": "Настройки профиля",
"Profile successfully saved": "Профиль успешно сохранён", "Profile successfully saved": "Профиль успешно сохранён",
"Profile": "Профиль",
"Publication settings": "Настройки публикации", "Publication settings": "Настройки публикации",
"Publications": "Публикации", "Publications": "Публикации",
"PublicationsWithCount": "{count, plural, =0 {нет публикаций} one {{count} публикация} few {{count} публикации} other {{count} публикаций}}", "PublicationsWithCount": "{count, plural, =0 {нет публикаций} one {{count} публикация} few {{count} публикации} other {{count} публикаций}}",
"Publish": "Опубликовать",
"Publish Album": "Опубликовать альбом", "Publish Album": "Опубликовать альбом",
"Publish Settings": "Настройки публикации", "Publish Settings": "Настройки публикации",
"Publish": "Опубликовать",
"Published": "Опубликованные", "Published": "Опубликованные",
"Punchline": "Панчлайн", "Punchline": "Панчлайн",
"Quit": "Выйти", "Quit": "Выйти",
@ -328,30 +327,30 @@
"Reports": "Репортажи", "Reports": "Репортажи",
"Required": "Поле обязательно для заполнения", "Required": "Поле обязательно для заполнения",
"Resend code": "Выслать подтверждение", "Resend code": "Выслать подтверждение",
"Restore password": "Восстановить пароль", "Set the new password": "Задать новый пароль",
"Rules of the journal Discours": "Правила журнала Дискурс", "Rules of the journal Discours": "Правила журнала Дискурс",
"Save": "Сохранить",
"Save draft": "Сохранить черновик", "Save draft": "Сохранить черновик",
"Save settings": "Сохранить настройки", "Save settings": "Сохранить настройки",
"Save": "Сохранить",
"Saving...": "Сохраняем...", "Saving...": "Сохраняем...",
"Scroll up": "Наверх", "Scroll up": "Наверх",
"Search": "Поиск",
"Search author": "Поиск автора", "Search author": "Поиск автора",
"Search topic": "Поиск темы", "Search topic": "Поиск темы",
"Search": "Поиск",
"Sections": "Разделы", "Sections": "Разделы",
"Security": "Безопасность", "Security": "Безопасность",
"Select": "Выбрать", "Select": "Выбрать",
"Self-publishing exists thanks to the help of wonderful people from all over the world. Thank you!": "Самиздат существуют благодаря помощи замечательных людей со всего мира. Спасибо Вам!", "Self-publishing exists thanks to the help of wonderful people from all over the world. Thank you!": "Самиздат существуют благодаря помощи замечательных людей со всего мира. Спасибо Вам!",
"Send": "Отправить",
"Send link again": "Прислать ссылку ещё раз", "Send link again": "Прислать ссылку ещё раз",
"Send": "Отправить",
"Settings": "Настройки", "Settings": "Настройки",
"Share": "Поделиться",
"Share publication": "Поделиться публикацией", "Share publication": "Поделиться публикацией",
"Share": "Поделиться",
"Short opening": "Расскажите вашу историю...", "Short opening": "Расскажите вашу историю...",
"Show": "Показать",
"Show lyrics": "Текст песни", "Show lyrics": "Текст песни",
"Show more": "Читать дальше", "Show more": "Читать дальше",
"Show table of contents": "Показать главление", "Show table of contents": "Показать главление",
"Show": "Показать",
"Site search": "Поиск по сайту", "Site search": "Поиск по сайту",
"Slug": "Постоянная ссылка", "Slug": "Постоянная ссылка",
"Social networks": "Социальные сети", "Social networks": "Социальные сети",
@ -370,12 +369,12 @@
"Start conversation": "Начать беседу", "Start conversation": "Начать беседу",
"Start dialog": "Начать диалог", "Start dialog": "Начать диалог",
"Subheader": "Подзаголовок", "Subheader": "Подзаголовок",
"Subscribe": "Подписаться",
"Subscribe to comments": "Подписаться на комментарии", "Subscribe to comments": "Подписаться на комментарии",
"Subscribe to the best publications newsletter": "Подпишитесь на рассылку лучших публикаций", "Subscribe to the best publications newsletter": "Подпишитесь на рассылку лучших публикаций",
"Subscribe us": "Подпишитесь на&nbsp;нас", "Subscribe us": "Подпишитесь на&nbsp;нас",
"Subscribe what you like to tune your personal feed": "Подпишитесь на интересующие вас темы, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях", "Subscribe what you like to tune your personal feed": "Подпишитесь на интересующие вас темы, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях",
"Subscribe who you like to tune your personal feed": "Подпишитесь на интересующих вас авторов, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях", "Subscribe who you like to tune your personal feed": "Подпишитесь на интересующих вас авторов, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях",
"Subscribe": "Подписаться",
"SubscriberWithCount": "{count, plural, =0 {нет подписчиков} one {{count} подписчик} few {{count} подписчика} other {{count} подписчиков}}", "SubscriberWithCount": "{count, plural, =0 {нет подписчиков} one {{count} подписчик} few {{count} подписчика} other {{count} подписчиков}}",
"Subscription": "Подписка", "Subscription": "Подписка",
"SubscriptionWithCount": "{count, plural, =0 {нет подписок} one {{count} подписка} few {{count} подписки} other {{count} подписок}}", "SubscriptionWithCount": "{count, plural, =0 {нет подписок} one {{count} подписка} few {{count} подписки} other {{count} подписок}}",
@ -389,8 +388,8 @@
"Support us": "Помочь журналу", "Support us": "Помочь журналу",
"Terms of use": "Правила сайта", "Terms of use": "Правила сайта",
"Text checking": "Проверка текста", "Text checking": "Проверка текста",
"Thank you": "Благодарности",
"Thank you!": "Спасибо Вам!", "Thank you!": "Спасибо Вам!",
"Thank you": "Благодарности",
"The address is already taken": "Адрес уже занят", "The address is already taken": "Адрес уже занят",
"The most interesting publications on the topic": "Самые интересные публикации по теме {topicName}", "The most interesting publications on the topic": "Самые интересные публикации по теме {topicName}",
"Thematic table of contents of the magazine. Here you can find all the topics that community authors have written about.": "Тематическое оглавление журнала. Здесь можно найти все темы, о которых писали авторы сообщества.", "Thematic table of contents of the magazine. Here you can find all the topics that community authors have written about.": "Тематическое оглавление журнала. Здесь можно найти все темы, о которых писали авторы сообщества.",
@ -400,7 +399,10 @@
"There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?": "В настройках вашего профиля есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?", "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?": "В настройках вашего профиля есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?",
"There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "В настройках публикации есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?", "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "В настройках публикации есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?",
"This comment has not yet been rated": "Этот комментарий еще пока никто не оценил", "This comment has not yet been rated": "Этот комментарий еще пока никто не оценил",
"This email is already taken. If it's you": "Такой email уже зарегистрирован. Если это вы", "This email is": "Этот email",
"This email is not verified": "Этот email не подтвержден",
"This email is verified": "Этот email подтвержден",
"This email is registered": "Этот email уже зарегистрирован",
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.", "This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.",
"This month": "За месяц", "This month": "За месяц",
"This post has not been rated yet": "Эту публикацию еще пока никто не оценил", "This post has not been rated yet": "Эту публикацию еще пока никто не оценил",
@ -420,36 +422,35 @@
"Top topics": "Интересные темы", "Top topics": "Интересные темы",
"Top viewed": "Самое читаемое", "Top viewed": "Самое читаемое",
"Topic is supported by": "Тему поддерживают", "Topic is supported by": "Тему поддерживают",
"Topics": "Темы",
"Topics which supported by author": "Автор поддерживает темы", "Topics which supported by author": "Автор поддерживает темы",
"Topics": "Темы",
"Try to find another way": "Попробуйте найти по-другому", "Try to find another way": "Попробуйте найти по-другому",
"Unfollow": "Отписаться",
"Unfollow the topic": "Отписаться от темы", "Unfollow the topic": "Отписаться от темы",
"Unfollow": "Отписаться",
"Unnamed draft": "Черновик без названия", "Unnamed draft": "Черновик без названия",
"Upload": "Загрузить",
"Upload error": "Ошибка загрузки", "Upload error": "Ошибка загрузки",
"Upload userpic": "Загрузить аватар", "Upload userpic": "Загрузить аватар",
"Upload video": "Загрузить видео", "Upload video": "Загрузить видео",
"Upload": "Загрузить",
"Uploading image": "Загружаем изображение", "Uploading image": "Загружаем изображение",
"User with this email already exists": "Пользователь с таким email уже существует",
"Username": "Имя пользователя", "Username": "Имя пользователя",
"Userpic": "Аватар", "Userpic": "Аватар",
"Users": "Пользователи", "Users": "Пользователи",
"Video": "Видео",
"Video format not supported": "Тип видео не поддерживается", "Video format not supported": "Тип видео не поддерживается",
"Video": "Видео",
"Views": "Просмотры", "Views": "Просмотры",
"We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues": "Мы работаем над коллаборативным редактированием статей и в ближайшем времени у вас появиться удивительная возможность - творить вместе с коллегами", "We are working on collaborative editing of articles and in the near future you will have an amazing opportunity - to create together with your colleagues": "Мы работаем над коллаборативным редактированием статей и в ближайшем времени у вас появиться удивительная возможность - творить вместе с коллегами",
"We can't find you, check email or": "Не можем вас найти, проверьте адрес электронной почты или", "We can't find you, check email or": "Не можем вас найти, проверьте адрес электронной почты или",
"We couldn't find anything for your request": "Мы&nbsp;не&nbsp;смогли ничего найти по&nbsp;вашему запросу", "We couldn't find anything for your request": "Мы&nbsp;не&nbsp;смогли ничего найти по&nbsp;вашему запросу",
"We know you, please try to login": "Такой адрес почты уже зарегистрирован, попробуйте залогиниться", "We know you, please try to login": "Такой адрес почты уже зарегистрирован, попробуйте залогиниться",
"We've sent you a message with a link to enter our website.": "Мы выслали вам письмо с ссылкой на почту. Перейдите по ссылке в письме, чтобы войти на сайт.", "We've sent you a message with a link to enter our website.": "Мы выслали вам письмо с ссылкой на почту. Перейдите по ссылке в письме, чтобы войти на сайт.",
"Welcome to Discours": "Добро пожаловать в Дискурс",
"Welcome to Discours to add to your bookmarks": "Войдите в Дискурс, чтобы добавить в закладки", "Welcome to Discours to add to your bookmarks": "Войдите в Дискурс, чтобы добавить в закладки",
"Welcome to Discours to participate in discussions": "Войдите в Дискурс для участия в дискуссиях", "Welcome to Discours to participate in discussions": "Войдите в Дискурс для участия в дискуссиях",
"Welcome to Discours to publish articles": "Войдите в Дискурс, чтобы публиковать статьи", "Welcome to Discours to publish articles": "Войдите в Дискурс, чтобы публиковать статьи",
"Welcome to Discours to subscribe": "Войдите в Дискурс для подписки на новые публикации",
"Welcome to Discours to subscribe to new publications": "Войдите в Дискурс, чтобы подписаться", "Welcome to Discours to subscribe to new publications": "Войдите в Дискурс, чтобы подписаться",
"Welcome to Discours to subscribe": "Войдите в Дискурс для подписки на новые публикации",
"Welcome to Discours to vote": "Войдите в Дискурс, чтобы голосовать", "Welcome to Discours to vote": "Войдите в Дискурс, чтобы голосовать",
"Welcome to Discours": "Добро пожаловать в Дискурс",
"Welcome!": "Добро пожаловать!", "Welcome!": "Добро пожаловать!",
"Where": "Откуда", "Where": "Откуда",
"Why you can earn a hole in your karma and how to receive rays of gratitude for your contribution to discussions in samizdat communities": "За что можно заслужить дырку в карме и как получить лучи благодарности за вклад в дискуссии в сообществах самиздата", "Why you can earn a hole in your karma and how to receive rays of gratitude for your contribution to discussions in samizdat communities": "За что можно заслужить дырку в карме и как получить лучи благодарности за вклад в дискуссии в сообществах самиздата",
@ -464,6 +465,7 @@
"Write message": "Написать сообщение", "Write message": "Написать сообщение",
"Write to us": "Напишите нам", "Write to us": "Напишите нам",
"Write your colleagues name or email": "Напишите имя или e-mail коллеги", "Write your colleagues name or email": "Напишите имя или e-mail коллеги",
"You can": "Вы можете",
"You can download multiple tracks at once in .mp3, .wav or .flac formats": "Можно загрузить сразу несколько треков в форматах .mp3, .wav или .flac", "You can download multiple tracks at once in .mp3, .wav or .flac formats": "Можно загрузить сразу несколько треков в форматах .mp3, .wav или .flac",
"You can now login using your new password": "Теперь вы можете входить с помощью нового пароля", "You can now login using your new password": "Теперь вы можете входить с помощью нового пароля",
"You was successfully authorized": "Вы были успешно авторизованы", "You was successfully authorized": "Вы были успешно авторизованы",
@ -496,7 +498,7 @@
"drafts": "черновики", "drafts": "черновики",
"earlier": "ранее", "earlier": "ранее",
"email not confirmed": "email не подтвержден", "email not confirmed": "email не подтвержден",
"enter": "войдите", "enter": "войти",
"feed": "лента", "feed": "лента",
"follower": "подписчик", "follower": "подписчик",
"followersWithCount": "{count} {count, plural, one {подписчик} few {подписчика} other {подписчиков}}", "followersWithCount": "{count} {count, plural, one {подписчик} few {подписчика} other {подписчиков}}",
@ -515,31 +517,35 @@
"min. 1400×1400 pix": "мин. 1400×1400 пикс.", "min. 1400×1400 pix": "мин. 1400×1400 пикс.",
"music": "музыка", "music": "музыка",
"my feed": "моя лента", "my feed": "моя лента",
"not verified": "ещё не подтверждён",
"number list": "нумер. список", "number list": "нумер. список",
"or": "или",
"or sign in with social networks": "или войдите через соцсеть", "or sign in with social networks": "или войдите через соцсеть",
"or": "или",
"personal data usage and email notifications": "на обработку персональных данных и на получение почтовых уведомлений", "personal data usage and email notifications": "на обработку персональных данных и на получение почтовых уведомлений",
"post": "пост", "post": "пост",
"principles keywords": "Discours.io, сообщества, ценности, правила редакции, многоголосие, созидание", "principles keywords": "Discours.io, сообщества, ценности, правила редакции, многоголосие, созидание",
"register": "зарегистрируйтесь", "register": "зарегистрируйтесь",
"registered": "уже зарегистрирован",
"repeat": "повторить", "repeat": "повторить",
"resend confirmation link": "отправить ссылку ещё раз",
"shout": "пост", "shout": "пост",
"shoutsWithCount": "{count} {count, plural, one {пост} few {поста} other {постов}}", "shoutsWithCount": "{count} {count, plural, one {пост} few {поста} other {постов}}",
"sign in": "войти", "sign in": "войти",
"sign up": "зарегистрироваться",
"sign up or sign in": "зарегистрироваться или войти", "sign up or sign in": "зарегистрироваться или войти",
"sign up": "зарегистрироваться",
"slug is used by another user": "Имя уже занято другим пользователем", "slug is used by another user": "Имя уже занято другим пользователем",
"squib": "Подверстка", "squib": "Подверстка",
"subscriber": "подписчик", "subscriber": "подписчик",
"subscriber_rp": "подписчика", "subscriber_rp": "подписчика",
"subscribers": "подписчиков", "subscribers": "подписчиков",
"subscribing...": "Подписка...", "subscribing...": "Подписка...",
"terms of use": "правилами пользования сайтом",
"terms of use keywords": "Discours.io, правила сайта, terms of use", "terms of use keywords": "Discours.io, правила сайта, terms of use",
"terms of use": "правилами пользования сайтом",
"today": "сегодня", "today": "сегодня",
"topicKeywords": "{topic}, Discours.io, статьи, журналистика, исследования", "topicKeywords": "{topic}, Discours.io, статьи, журналистика, исследования",
"topics": "темы", "topics": "темы",
"user already exist": "пользователь уже существует", "user already exist": "пользователь уже существует",
"verified": "уже подтверждён",
"video": "видео", "video": "видео",
"view": "просмотр", "view": "просмотр",
"viewsWithCount": "{count} {count, plural, one {просмотр} few {просмотрa} other {просмотров}}", "viewsWithCount": "{count} {count, plural, one {просмотр} few {просмотрa} other {просмотров}}",

View File

@ -71,7 +71,7 @@ export const AuthorBadge = (props: Props) => {
on( on(
() => props.isFollowed, () => props.isFollowed,
() => { () => {
setIsFollowed(props.isFollowed.value) setIsFollowed(props.isFollowed?.value)
}, },
), ),
) )

View File

@ -198,6 +198,14 @@
border-color: var(--background-color-invert); border-color: var(--background-color-invert);
} }
} }
&.info,
&.info a {
color: var(--secondary-color);
border-color: var(--secondary-color);
}
} }
.title { .title {

View File

@ -54,7 +54,7 @@ export const LoginForm = () => {
setIsLinkSent(true) setIsLinkSent(true)
setIsEmailNotConfirmed(false) setIsEmailNotConfirmed(false)
setSubmitError('') setSubmitError('')
changeSearchParams({ mode: 'forgot-password' }) changeSearchParams({ mode: 'send-reset-link' })
// NOTE: temporary solution, needs logic in authorizer // NOTE: temporary solution, needs logic in authorizer
/* FIXME: /* FIXME:
const { authorizer } = useSession() const { authorizer } = useSession()
@ -87,7 +87,7 @@ export const LoginForm = () => {
authFormRef.current authFormRef.current
.querySelector<HTMLInputElement>(`input[name="${Object.keys(newValidationErrors)[0]}"]`) .querySelector<HTMLInputElement>(`input[name="${Object.keys(newValidationErrors)[0]}"]`)
.focus() ?.focus()
return return
} }
@ -171,11 +171,11 @@ export const LoginForm = () => {
class="link" class="link"
onClick={() => onClick={() =>
changeSearchParams({ changeSearchParams({
mode: 'forgot-password', mode: 'send-reset-link',
}) })
} }
> >
{t('Forgot password?')} {t('Set the new password')}
</span> </span>
</div> </div>
</div> </div>

View File

@ -8,9 +8,12 @@ import styles from './PasswordField.module.scss'
type Props = { type Props = {
class?: string class?: string
disabled?: boolean
placeholder?: string
errorMessage?: (error: string) => void errorMessage?: (error: string) => void
onInput: (value: string) => void onInput: (value: string) => void
variant?: 'login' | 'registration' variant?: 'login' | 'registration'
disableAutocomplete?: boolean
} }
export const PasswordField = (props: Props) => { export const PasswordField = (props: Props) => {
@ -66,9 +69,10 @@ export const PasswordField = (props: Props) => {
<input <input
id="password" id="password"
name="password" name="password"
autocomplete="current-password" disabled={props.disabled}
autocomplete={props.disableAutocomplete ? 'one-time-code' : 'current-password'}
type={showPassword() ? 'text' : 'password'} type={showPassword() ? 'text' : 'password'}
placeholder={t('Password')} placeholder={props.placeholder || t('Password')}
onInput={(event) => handleInputChange(event.currentTarget.value)} onInput={(event) => handleInputChange(event.currentTarget.value)}
/> />
<label for="password">{t('Password')}</label> <label for="password">{t('Password')}</label>

View File

@ -1,12 +1,11 @@
import type { JSX } from 'solid-js' import type { JSX } from 'solid-js'
import { Show, createMemo, createSignal } from 'solid-js'
import type { AuthModalSearchParams } from './types' import type { AuthModalSearchParams } from './types'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import { Show, createSignal } from 'solid-js'
import { useLocalize } from '../../../context/localize' import { useLocalize } from '../../../context/localize'
import { useSession } from '../../../context/session' import { useSession } from '../../../context/session'
import { checkEmail, useEmailChecks } from '../../../stores/emailChecks'
import { useRouter } from '../../../stores/router' import { useRouter } from '../../../stores/router'
import { hideModal } from '../../../stores/ui' import { hideModal } from '../../../stores/ui'
import { validateEmail } from '../../../utils/validateEmail' import { validateEmail } from '../../../utils/validateEmail'
@ -16,8 +15,11 @@ import { PasswordField } from './PasswordField'
import { SocialProviders } from './SocialProviders' import { SocialProviders } from './SocialProviders'
import { email, setEmail } from './sharedLogic' import { email, setEmail } from './sharedLogic'
import { GenericResponse } from '@authorizerdev/authorizer-js'
import styles from './AuthModal.module.scss' import styles from './AuthModal.module.scss'
type EmailStatus = 'not verified' | 'verified' | 'registered' | ''
type FormFields = { type FormFields = {
fullName: string fullName: string
email: string email: string
@ -33,8 +35,7 @@ const handleEmailInput = (newEmail: string) => {
export const RegisterForm = () => { export const RegisterForm = () => {
const { changeSearchParams } = useRouter<AuthModalSearchParams>() const { changeSearchParams } = useRouter<AuthModalSearchParams>()
const { t } = useLocalize() const { t } = useLocalize()
const { emailChecks } = useEmailChecks() const { signUp, isRegistered, resendVerifyEmail } = useSession()
const { signUp } = useSession()
const [submitError, setSubmitError] = createSignal('') const [submitError, setSubmitError] = createSignal('')
const [fullName, setFullName] = createSignal('') const [fullName, setFullName] = createSignal('')
const [password, setPassword] = createSignal('') const [password, setPassword] = createSignal('')
@ -42,15 +43,10 @@ export const RegisterForm = () => {
const [isSuccess, setIsSuccess] = createSignal(false) const [isSuccess, setIsSuccess] = createSignal(false)
const [validationErrors, setValidationErrors] = createSignal<ValidationErrors>({}) const [validationErrors, setValidationErrors] = createSignal<ValidationErrors>({})
const [passwordError, setPasswordError] = createSignal<string>() const [passwordError, setPasswordError] = createSignal<string>()
const [emailStatus, setEmailStatus] = createSignal<string>('')
const authFormRef: { current: HTMLFormElement } = { current: null } const authFormRef: { current: HTMLFormElement } = { current: null }
const handleEmailBlur = () => {
if (validateEmail(email())) {
checkEmail(email())
}
}
const handleNameInput = (newName: string) => { const handleNameInput = (newName: string) => {
setFullName(newName) setFullName(newName)
} }
@ -86,17 +82,16 @@ export const RegisterForm = () => {
} }
setValidationErrors(newValidationErrors) setValidationErrors(newValidationErrors)
const emailCheckResult = await checkEmail(cleanEmail)
const isValid = Object.keys(newValidationErrors).length === 0 && !emailCheckResult
if (!isValid) { const isValid = createMemo(() => Object.keys(newValidationErrors).length === 0)
if (!isValid()) {
authFormRef.current authFormRef.current
.querySelector<HTMLInputElement>(`input[name="${Object.keys(newValidationErrors)[0]}"]`) .querySelector<HTMLInputElement>(`input[name="${Object.keys(newValidationErrors)[0]}"]`)
.focus() .focus()
return return
} }
setIsSubmitting(true) setIsSubmitting(true)
try { try {
const opts = { const opts = {
@ -107,26 +102,7 @@ export const RegisterForm = () => {
redirect_uri: window.location.origin, redirect_uri: window.location.origin,
} }
const { errors } = await signUp(opts) const { errors } = await signUp(opts)
if (errors?.some((error) => error.message.includes('has already signed up'))) { if (errors) return
setValidationErrors((prev) => ({
...prev,
email: (
<>
{t('User with this email already exists')},{' '}
<span
class={'link'}
onClick={() =>
changeSearchParams({
mode: 'login',
})
}
>
{t('sign in')}
</span>
</>
),
}))
}
setIsSuccess(true) setIsSuccess(true)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
@ -135,6 +111,69 @@ export const RegisterForm = () => {
} }
} }
const handleResendLink = async (_ev) => {
const response: GenericResponse = await resendVerifyEmail({
email: email(),
identifier: 'basic_signup',
})
setIsSuccess(response?.message === 'Verification email has been sent. Please check your inbox')
}
const handleCheckEmailStatus = (status: EmailStatus | string) => {
switch (status) {
case 'not verified':
setValidationErrors((prev) => ({
...prev,
email: (
<>
{t('This email is not verified')},{' '}
<span class="link" onClick={handleResendLink}>
{t('resend confirmation link')}
</span>
</>
),
}))
break
case 'verified':
setValidationErrors((prev) => ({
email: (
<>
{t('This email is verified')}. {t('You can')}
<span class="link" onClick={() => changeSearchParams({ mode: 'login' })}>
{t('enter')}
</span>
</>
),
}))
break
case 'registered':
setValidationErrors((prev) => ({
...prev,
email: (
<>
{t('This email is registered')}. {t('You can')}{' '}
<span class="link" onClick={() => changeSearchParams({ mode: 'send-reset-link' })}>
{t('Set the new password').toLocaleLowerCase()}
</span>
</>
),
}))
break
default:
console.info('[RegisterForm] email is not registered')
break
}
}
const handleEmailBlur = async () => {
if (validateEmail(email())) {
const checkResult = await isRegistered(email())
setEmailStatus(checkResult)
handleCheckEmailStatus(checkResult)
}
}
return ( return (
<> <>
<Show when={!isSuccess()}> <Show when={!isSuccess()}>
@ -154,52 +193,50 @@ export const RegisterForm = () => {
<input <input
name="fullName" name="fullName"
type="text" type="text"
disabled={Boolean(emailStatus())}
placeholder={t('Full name')} placeholder={t('Full name')}
autocomplete="" autocomplete="one-time-code"
onInput={(event) => handleNameInput(event.currentTarget.value)} onInput={(event) => handleNameInput(event.currentTarget.value)}
/> />
<label for="name">{t('Full name')}</label> <label for="name">{t('Full name')}</label>
<Show when={validationErrors().fullName}> <Show when={validationErrors().fullName && !emailStatus()}>
<div class={styles.validationError}>{validationErrors().fullName}</div> <div class={styles.validationError}>{validationErrors().fullName}</div>
</Show> </Show>
</div> </div>
<div <div
class={clsx('pretty-form__item', { class={clsx('pretty-form__item', {
'pretty-form__item--error': validationErrors().email, 'pretty-form__item--error': validationErrors().email && !emailStatus(),
})} })}
> >
<input <input
id="email" id="email"
name="email" name="email"
autocomplete="email" autocomplete="one-time-code"
type="email" type="email"
value={email()}
placeholder={t('Email')} placeholder={t('Email')}
onInput={(event) => handleEmailInput(event.currentTarget.value)} onInput={(event) => handleEmailInput(event.currentTarget.value)}
onBlur={handleEmailBlur} onBlur={handleEmailBlur}
/> />
<label for="email">{t('Email')}</label> <label for="email">{t('Email')}</label>
<Show when={validationErrors().email}> <div class={clsx(styles.validationError, { info: Boolean(emailStatus()) })}>
<div class={styles.validationError}>{validationErrors().email}</div> {validationErrors().email}
</Show>
<Show when={emailChecks()[email()]}>
<div class={styles.validationError}>
{t("This email is already taken. If it's you")},{' '}
<span class="link" onClick={() => changeSearchParams({ mode: 'login' })}>
{t('enter')}
</span>
</div> </div>
</Show>
</div> </div>
<PasswordField <PasswordField
disableAutocomplete={true}
disabled={Boolean(emailStatus())}
errorMessage={(err) => setPasswordError(err)} errorMessage={(err) => setPasswordError(err)}
onInput={(value) => setPassword(value)} onInput={(value) => setPassword(value)}
/> />
<div> <div>
<button class={clsx('button', styles.submitButton)} disabled={isSubmitting()} type="submit"> <button
class={clsx('button', styles.submitButton)}
disabled={isSubmitting() || Boolean(emailStatus())}
type="submit"
>
{isSubmitting() ? '...' : t('Join')} {isSubmitting() ? '...' : t('Join')}
</button> </button>
</div> </div>

View File

@ -18,7 +18,7 @@ type FormFields = {
type ValidationErrors = Partial<Record<keyof FormFields, string | JSX.Element>> type ValidationErrors = Partial<Record<keyof FormFields, string | JSX.Element>>
export const ForgotPasswordForm = () => { export const SendResetLinkForm = () => {
const { changeSearchParams } = useRouter<AuthModalSearchParams>() const { changeSearchParams } = useRouter<AuthModalSearchParams>()
const { t } = useLocalize() const { t } = useLocalize()
const handleEmailInput = (newEmail: string) => { const handleEmailInput = (newEmail: string) => {
@ -60,7 +60,7 @@ export const ForgotPasswordForm = () => {
email: email(), email: email(),
redirect_uri: window.location.origin, redirect_uri: window.location.origin,
}) })
console.debug('[ForgotPasswordForm] authorizer response:', data) console.debug('[SendResetLinkForm] authorizer response:', data)
if (errors?.some((error) => error.message.includes('bad user credentials'))) { if (errors?.some((error) => error.message.includes('bad user credentials'))) {
setIsUserNotFound(true) setIsUserNotFound(true)
} }
@ -79,10 +79,8 @@ export const ForgotPasswordForm = () => {
ref={(el) => (authFormRef.current = el)} ref={(el) => (authFormRef.current = el)}
> >
<div> <div>
<h4>{t('Restore password')}</h4> <h4>{t('Set the new password')}</h4>
<div class={styles.authSubtitle}> <div class={styles.authSubtitle}>{t(message()) || t('Please give us your email address')}</div>
{t(message()) || t('Everything is ok, please give us your email address')}
</div>
<div <div
class={clsx('pretty-form__item', { class={clsx('pretty-form__item', {
'pretty-form__item--error': validationErrors().email, 'pretty-form__item--error': validationErrors().email,
@ -126,7 +124,7 @@ export const ForgotPasswordForm = () => {
disabled={isSubmitting() || Boolean(message())} disabled={isSubmitting() || Boolean(message())}
type="submit" type="submit"
> >
{isSubmitting() ? '...' : t('Restore password')} {isSubmitting() ? '...' : t('Send')}
</button> </button>
</div> </div>
<div class={styles.authControl}> <div class={styles.authControl}>

View File

@ -11,16 +11,16 @@ import { isMobile } from '../../../utils/media-query'
import { ChangePasswordForm } from './ChangePasswordForm' import { ChangePasswordForm } from './ChangePasswordForm'
import { EmailConfirm } from './EmailConfirm' import { EmailConfirm } from './EmailConfirm'
import { ForgotPasswordForm } from './ForgotPasswordForm'
import { LoginForm } from './LoginForm' import { LoginForm } from './LoginForm'
import { RegisterForm } from './RegisterForm' import { RegisterForm } from './RegisterForm'
import { SendResetLinkForm } from './SendResetLinkForm'
import styles from './AuthModal.module.scss' import styles from './AuthModal.module.scss'
const AUTH_MODAL_MODES: Record<AuthModalMode, Component> = { const AUTH_MODAL_MODES: Record<AuthModalMode, Component> = {
login: LoginForm, login: LoginForm,
register: RegisterForm, register: RegisterForm,
'forgot-password': ForgotPasswordForm, 'send-reset-link': SendResetLinkForm,
'confirm-email': EmailConfirm, 'confirm-email': EmailConfirm,
'change-password': ChangePasswordForm, 'change-password': ChangePasswordForm,
} }

View File

@ -1,4 +1,4 @@
export type AuthModalMode = 'login' | 'register' | 'confirm-email' | 'forgot-password' | 'change-password' export type AuthModalMode = 'login' | 'register' | 'confirm-email' | 'send-reset-link' | 'change-password'
export type AuthModalSource = export type AuthModalSource =
| 'discussions' | 'discussions'
| 'vote' | 'vote'

View File

@ -11,6 +11,7 @@ import {
ForgotPasswordResponse, ForgotPasswordResponse,
GenericResponse, GenericResponse,
LoginInput, LoginInput,
ResendVerifyEmailInput,
SignupInput, SignupInput,
VerifyEmailInput, VerifyEmailInput,
} from '@authorizerdev/authorizer-js' } from '@authorizerdev/authorizer-js'
@ -68,6 +69,8 @@ export type SessionContextType = {
confirmEmail: (input: VerifyEmailInput) => Promise<AuthToken> // email confirm callback is in auth.discours.io confirmEmail: (input: VerifyEmailInput) => Promise<AuthToken> // email confirm callback is in auth.discours.io
setIsSessionLoaded: (loaded: boolean) => void setIsSessionLoaded: (loaded: boolean) => void
authorizer: () => Authorizer authorizer: () => Authorizer
isRegistered: (email: string) => Promise<string>
resendVerifyEmail: (params: ResendVerifyEmailInput) => Promise<GenericResponse>
} }
const noop = () => {} const noop = () => {}
@ -309,6 +312,31 @@ export const SessionProvider = (props: {
return { data: resp?.data, errors: resp.errors } return { data: resp?.data, errors: resp.errors }
} }
const resendVerifyEmail = async (params: ResendVerifyEmailInput) => {
const resp = await authorizer().resendVerifyEmail(params)
console.debug('[context.session] resend verify email response:', resp)
if (resp.errors) {
resp.errors.forEach((error) => {
showSnackbar({ type: 'error', body: error.message })
})
}
return resp?.data
}
const isRegistered = async (email: string): Promise<string> => {
console.debug('[context.session] calling is_registered for ', email)
try {
const response = await authorizer().graphqlQuery({
query: `query { is_registered(email: "${email}") { message }}`,
})
// console.log(response)
return response?.data?.is_registered?.message
} catch (error) {
console.warn(error)
}
return ''
}
const confirmEmail = async (input: VerifyEmailInput) => { const confirmEmail = async (input: VerifyEmailInput) => {
console.debug(`[context.session] calling authorizer's verify email with`, input) console.debug(`[context.session] calling authorizer's verify email with`, input)
try { try {
@ -348,6 +376,7 @@ export const SessionProvider = (props: {
forgotPassword, forgotPassword,
changePassword, changePassword,
oauth, oauth,
isRegistered,
} }
const value: SessionContextType = { const value: SessionContextType = {
authError, authError,
@ -357,6 +386,7 @@ export const SessionProvider = (props: {
author, author,
...actions, ...actions,
isAuthenticated, isAuthenticated,
resendVerifyEmail,
} }
return <SessionContext.Provider value={value}>{props.children}</SessionContext.Provider> return <SessionContext.Provider value={value}>{props.children}</SessionContext.Provider>

View File

@ -1,21 +0,0 @@
import { createSignal } from 'solid-js'
const [emailChecks, setEmailChecks] = createSignal<{ [email: string]: boolean }>({})
export const checkEmail = async (email: string): Promise<boolean> => {
if (emailChecks()[email]) {
return true
}
const checkResult = false // FIXME: secure endpoint for check email
if (checkResult) {
setEmailChecks((oldEmailChecks) => ({ ...oldEmailChecks, [email]: true }))
return true
}
return false
}
export const useEmailChecks = () => {
return { emailChecks }
}

View File

@ -51,7 +51,8 @@ export default defineConfig(({ mode, command }) => {
envPrefix: 'PUBLIC_', envPrefix: 'PUBLIC_',
plugins, plugins,
server: { server: {
https: true, cors: isDev,
https: {},
port: 3000, port: 3000,
}, },
css: { css: {
@ -78,6 +79,8 @@ export default defineConfig(({ mode, command }) => {
'wonka', 'wonka',
'solid-popper', 'solid-popper',
'seroval', 'seroval',
'seroval-plugins',
'seroval-plugins/web',
'@solid-primitives/share', '@solid-primitives/share',
'i18next', 'i18next',
'js-cookie', 'js-cookie',