@@ -112,6 +133,7 @@ export const ColumnsArea = forwardRef<
+
{children}
diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js
index 1e21730a00..8abbbefe14 100644
--- a/app/javascript/mastodon/features/ui/containers/status_list_container.js
+++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js
@@ -11,7 +11,15 @@ import { me } from '@/mastodon/initial_state';
const makeGetStatusIds = (pending = false) => createSelector([
(state, { type }) => state.getIn(['settings', type], ImmutableMap()),
- (state, { type }) => state.getIn(['timelines', type, pending ? 'pendingItems' : 'items'], ImmutableList()),
+ (state, { type, maxItems }) => {
+ const items = state.getIn(['timelines', type, pending ? 'pendingItems' : 'items'], ImmutableList());
+
+ if (maxItems) {
+ return items.take(maxItems);
+ }
+
+ return items;
+ },
(state) => state.get('statuses'),
], (columnSettings, statusIds, statuses) => {
return statusIds.filter(id => {
@@ -41,8 +49,15 @@ const makeMapStateToProps = () => {
const getStatusIds = makeGetStatusIds();
const getPendingStatusIds = makeGetStatusIds(true);
- const mapStateToProps = (state, { timelineId, initialLoadingState = true }) => ({
- statusIds: getStatusIds(state, { type: timelineId }),
+ /**
+ * @param {import('mastodon/store').RootState} state
+ * @param {Object} props
+ * @param {string} props.timelineId
+ * @param {boolean} [props.initialLoadingState]
+ * @param {number} [props.maxItems]
+ */
+ const mapStateToProps = (state, { timelineId, initialLoadingState = true, maxItems }) => ({
+ statusIds: getStatusIds(state, { type: timelineId, maxItems }),
lastId: state.getIn(['timelines', timelineId, 'items'])?.last(),
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], initialLoadingState),
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx
index 733a91d041..1bf0842cb8 100644
--- a/app/javascript/mastodon/features/ui/index.jsx
+++ b/app/javascript/mastodon/features/ui/index.jsx
@@ -29,7 +29,7 @@ import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../act
import { clearHeight } from '../../actions/height_cache';
import { fetchServer, fetchServerTranslationLanguages } from '../../actions/server';
import { expandHomeTimeline } from '../../actions/timelines';
-import { initialState, me, owner, singleUserMode, trendsEnabled, landingPage, localLiveFeedAccess, disableHoverCards } from '../../initial_state';
+import { initialState, me, owner, singleUserMode, trendsEnabled, landingPage, localLiveFeedAccess, disableHoverCards, domain } from '../../initial_state';
import BundleColumnError from './components/bundle_column_error';
import { NavigationBar } from './components/navigation_bar';
@@ -88,6 +88,7 @@ import {
import { ColumnsContextProvider } from './util/columns_context';
import { focusColumn, getFocusedItemIndex, focusItemSibling, focusFirstItem } from './util/focusUtils';
import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
+import { CustomHomepage } from 'mastodon/features/custom_homepage';
// Dummy import, to make sure that
ends up in the application bundle.
// Without this it ends up in ~8 very commonly used bundles.
@@ -177,13 +178,15 @@ class SwitchingColumnsArea extends PureComponent {
rootRedirect = '/explore';
} else if (localLiveFeedAccess === 'public' && landingPage === 'local_feed') {
rootRedirect = '/public/local';
+ } else if (landingPage === 'overview') {
+ rootRedirect = '/overview';
} else {
rootRedirect = '/about';
}
return (
-
+
@@ -262,6 +265,8 @@ class SwitchingColumnsArea extends PureComponent {
+
+
@@ -633,13 +638,18 @@ class UI extends PureComponent {
cheat: this.handleDonate,
};
+ const minimalShell = !this.props.identity.signedIn && landingPage === 'overview';
+
return (
-
+ {!minimalShell && (
+
+ )}
+
-
+ {!minimalShell && }
{layout !== 'mobile' && }
{!disableHoverCards && }
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index df12731eda..b97260173b 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -584,6 +584,12 @@
"copy_icon_button.copy_this_text": "Copy link to clipboard",
"copypaste.copied": "Copied",
"copypaste.copy_to_clipboard": "Copy to clipboard",
+ "custom_homepage.about": "About",
+ "custom_homepage.about_this_server": "About this server",
+ "custom_homepage.administered_by": "Administered by",
+ "custom_homepage.contact": "Contact:",
+ "custom_homepage.latest_activity": "Latest activity",
+ "custom_homepage.these_are_the_latest_posts": "These are the latest 40 posts from accounts on this server.",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index 0ad5335419..5e97151438 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -94,7 +94,7 @@ class Form::AdminSettings
REGISTRATION_MODES = %w(open approved none).freeze
FEED_ACCESS_MODES = %w(public authenticated disabled).freeze
ALTERNATE_FEED_ACCESS_MODES = %w(public authenticated).freeze
- LANDING_PAGE = %w(trends about local_feed).freeze
+ LANDING_PAGE = %w(trends overview local_feed about).freeze
attr_accessor(*KEYS)
diff --git a/app/views/admin/settings/branding/show.html.haml b/app/views/admin/settings/branding/show.html.haml
index 65aae77d5f..9e9653abf1 100644
--- a/app/views/admin/settings/branding/show.html.haml
+++ b/app/views/admin/settings/branding/show.html.haml
@@ -75,10 +75,11 @@
.fields-row
= f.input :landing_page,
+ as: :radio_buttons,
collection: f.object.class::LANDING_PAGE,
include_blank: false,
- label_method: ->(page) { I18n.t("admin.settings.landing_page.values.#{page}") },
- wrapper: :with_label
+ label_method: ->(page) { safe_join([I18n.t("admin.settings.landing_page.values.#{page}"), content_tag(:span, I18n.t("admin.settings.landing_page.hints.#{page}_html"), class: 'hint')]) },
+ wrapper: :with_block_label
.actions
= f.button :button, t('generic.save_changes'), type: :submit
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2ed8dd1c1a..f47eac1fe1 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -956,10 +956,16 @@ en:
disabled: Require specific user role
public: Everyone
landing_page:
+ hints:
+ about_html: A page with the description, contact information, rules and other information regarding this server.
+ local_feed_html: A live feed featuring most recent posts by users on this server.
+ overview_html: A page showcasing the description of your server alongside the most recent local posts by users on this server.
+ trends_html: A page featuring what's popular on this server right now.
values:
- about: About
- local_feed: Local feed
- trends: Trends
+ about: About page
+ local_feed: Local live feed
+ overview: Overview
+ trends: Trending
registrations:
moderation_recommandation: Please make sure you have an adequate and reactive moderation team before you open registrations to everyone!
preamble: Control who can create an account on your server.
diff --git a/config/routes/web_app.rb b/config/routes/web_app.rb
index cb85dc8753..22814f294c 100644
--- a/config/routes/web_app.rb
+++ b/config/routes/web_app.rb
@@ -33,4 +33,6 @@
/search
/start/(*any)
/statuses/(*any)
+ /overview
+ /overview/about
).each { |path| get path, to: 'home#index' }