diff --git a/.gitignore b/.gitignore index 1e1b9608..79249b1b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,16 +32,11 @@ public/.well-known public/avatars public/sitemap* -# templates to be created per-site -app/views/about/404.* -app/views/about/about.* -app/views/about/chat.* -app/views/about/privacy.* -public/apple-touch-icon* -public/favicon.ico - # prod config config/credentials.yml.enc + +# files added in production +lib/tasks/deploy.rake config/database.yml config/initializers/development.rb config/initializers/production.rb @@ -49,4 +44,5 @@ config/master.key config/scout_apm.yml config/*.sphinx.conf config/unicorn.conf.rb -lib/tasks/deploy.rake +config/scout_apm.yml +.env diff --git a/app/assets/stylesheets/application.css.erb b/app/assets/stylesheets/application.css.erb index fdbcb205..20e25c16 100644 --- a/app/assets/stylesheets/application.css.erb +++ b/app/assets/stylesheets/application.css.erb @@ -233,10 +233,10 @@ html { } body, textarea, input, button { - font-family: "helvetica neue", arial, sans-serif; - font-size: 10pt; + font-family: "IBM Plex Mono", "JetBrains Mono", Consolas, "Courier New", Courier, monospace; + font-size: 11pt; color: var(--color-fg); - line-height: 1.45em; + line-height: 1.35em; } body { diff --git a/app/assets/stylesheets/local/lobsters.css b/app/assets/stylesheets/local/lobsters.css new file mode 100644 index 00000000..2736adb3 --- /dev/null +++ b/app/assets/stylesheets/local/lobsters.css @@ -0,0 +1,69 @@ +/* light mode */ +:root { + --color-lobsters-fg-has-suggestions: #bd6060; + + --color-lobsters-tag-special-bg: #f9ddde; + --color-lobsters-tag-special-border: #f0b2b8; + + --color-lobsters-hat-sysop-crown-fill: #ddc7c7; + --color-lobsters-hat-sysop-brim-stroke: #bbb2b2; +} + +/* dark mode */ +@media (prefers-color-scheme: dark) { + :root { + --color-lobsters-fg-has-suggestions: #df7171; + + --color-lobsters-tag-special-bg: #3b1719; + --color-lobsters-tag-special-border: #611a21; + + --color-lobsters-hat-sysop-crown-fill: #3e2f2f; + --color-lobsters-hat-sysop-brim-stroke: #2c2222; + } +} + +li .byline a.story_has_suggestions { + color: var(--color-lobsters-fg-has-suggestions); +} + +a.tag_announce, a.tag_ask, a.tag_show, a.tag_interview { + background-color: var(--color-lobsters-tag-special-bg); + border-color: var(--color-lobsters-tag-special-border); + color: var(--color-fg-67); +} + +span.hat_openbsd_developer span.crown { + font-family: comic sans ms, comic sans, comic neue, sans-serif; + font-size: 7pt; +} + +span.hat_sysop { + border-color: var(--color-lobsters-hat-sysop-brim-stroke); + color: var(--color-fg-67); +} +span.hat_sysop span.crown { + background-color: var(--color-lobsters-hat-sysop-crown-fill); +} + +#l_holder { + position: relative; +} +#l_holder:after { + content: ''; + background: transparent url("/favicon-16x16.png") no-repeat center; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +@media +only screen and (min-resolution: 2dppx), +only screen and (-webkit-min-device-pixel-ratio: 2) { + #l_holder { + background: transparent url("/favicon-16x16.png") no-repeat; + background-size: 16px; + background-position: 1px 1px; + } +} diff --git a/app/models/user.rb b/app/models/user.rb index 0d68d209..e61f2bdc 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -143,7 +143,7 @@ class User < ApplicationRecord "sysop", "webmaster", "enable", "new", "signup"].freeze # days old accounts are considered new for - NEW_USER_DAYS = 70 + NEW_USER_DAYS = 7 # minimum karma required to be able to offer title/tag suggestions MIN_KARMA_TO_SUGGEST = 10 diff --git a/app/views/about/about.html.erb b/app/views/about/about.html.erb index 7551fb51..82af547b 100644 --- a/app/views/about/about.html.erb +++ b/app/views/about/about.html.erb @@ -1,369 +1,14 @@ -<% render partial: 'about/subnav' %> -
- Lobsters is a computing-focused community centered around link aggregation - and discussion, launched on July 3rd, 2012. - The administrator is Peter Bhat Harkins ("pushcx"), contact him with any support issues. - Lobsters was created by joshua stein - with careful design touches to encourage a healthy community: -
- -- When links or stories are submitted, they must be tagged by the submitter from a list of predefined tags. - Users can choose to filter out or - subscribe to all submissions with particular tags (example: programming.rss) - or combinations of tags (example: programming,audio.rss). - All users see all stories by default. - The tagging system works this way for three reasons: -
- -- It keeps the site on-topic by only allowing a predefined list of tags. - These tags represent what most of the users of the site want to read, so - content that does not fit into any of those categories should not be - submitted. It also keeps stories organized and more easily searchable. -
- It promotes discussion. On a site with separate forums, a Ruby programmer - would probably subscribe to a Ruby forum, but not a Python one. When a link - is posted to the Python forum, that Ruby programmer would probably never see - it, even though they may have something useful to say about it (perhaps the - link is about a Python library which does the same thing as a Ruby library - which that Ruby programmer created). On this site, the link would get posted - with a python tag and shown to everyone, - encouraging the Ruby programmer to read and comment on it (unless that Ruby - programmer disliked Python enough to filter it out). -
- It keeps the community coherent. Often stories contain discussion - about more than one topic, yet on other sites they are confined to a single - category/forum, limiting the exposure. The link could be submitted to more - than one forum, but then each conversation would remain separate and users - would rarely interact with users from other forums. On this site, the story - would simply be tagged with multiple tags and all users would see all - discussion about the story in a single location. -
- Creating new tags and retiring old tags is done by the community by submitting, discussing, and voting on meta-tagged requests about them, - and these events are logged (since 2018-04). - To propose a tag, post a meta thread with the name and description. - Explain the scope, list existing stories that should have been tagged, make a case for why people would want to specifically filter it out, and justify the increased complexity for submitters and mods. -
- -- Lobsters is focused pretty narrowly on computing; tags like art don't imply every piece of art is on-topic. - Some rules of thumb for great stories to submit: Will this improve the reader's next program? Will it deepen their understanding of their last program? Will it be more interesting in five or ten years? -
- -- Some things that are off-topic here but popular on larger, similar sites: - entrepreneurship, management, news about companies that employ a lot of programmers, - investing, world events, anthropology, self-help, personal productivity systems, - last-resort customer service requests via public shaming, - "I wanted to see what this site's amazing users think about this off-topic thing", - and - defining the single morally correct economic and political system for the entire world when we can't even settle tabs vs. spaces. -
-- The full <%= link_to 'user tree', users_tree_path %> is public and each user's profile - shows who invited them. This provides some degree of accountability and - helps identify voting rings. -
- -- Invitations are used as a mechanism for spam-control, - to slow registrations to a pace we can acculturate (more below) - and to encourage users to be nice, not to make the Lobsters userbase an elite club. - Users are considered "new" for their first <%= User::NEW_USER_DAYS %> days, - and their usernames appear in green. - New users can't - send invites, - submit links to domains we haven't seen submitted before, - flag stories and comments, - suggest edits to story titles and tags, - resubmit links that have been seen before, - or - -
- -- The quickest way to receive an invitation is to talk to someone you <%= link_to 'recognize from the site', users_tree_path %>. - If you wrote a link that was posted, please reach out in chat, we'd love to have you join the discussion. - Finally, if you can't find anyone you know in the invitation tree and didn't author something posted to the site, - <% if Rails.application.allow_invitation_requests? %> - you can request an invite. - <% else %> - consider getting to know the community in the chat room. - <% end %> -
- -- There's no limit on how many invitations a user can send (though we might at some point, to manage growth). - There's also no official vetting process for new users, each user is responsible for inviting people they believe will contribute positively to Lobsters. - When accounts are banned for spam, sockpuppeting, or other abuse, - moderators will consider disabling their inviter's ability to send invitations or, rarely, also ban them. -
- -- All story and comment ranking on this site comes from user activity. - All users have equal votes, with no special priorities or penalties for specific users or domains. - Moderators have no ability to raise or lower the rankings of stories or comments (besides voting like any user). - Per-tag hotness modifiers affect all stories with - those tags, but these modifiers (and changes to them) are public. - Domains used for marketing analytics are banned and tracking parameters are removed from links - (look for TRACKING_DOMAINS and utm_ in story.rb). -
- -- Users can flag stories and comments when there's a serious problem that needs moderator attention; two flags are needed to add the story or comment to the moderation queue. - Users must reach <%= User::MIN_KARMA_TO_FLAG %> karma to flag. - To guide usage and head off distracting meta conversations ("Why was this flagged!?", etc), flagging requires selecting from a preset list of reasons. -
- -- For stories, these are: - "Off-topic" for stories that are not about computing; - "Already Posted" for duplicate submissions and links that elaborate on or responses to a thread that's less than a week old (see merging); and - "Broken Link" for links that 404, 500, or present a paywall; - "Spam" for links that promote a commercial service. -
- -- For comments, these are: - "Off-topic" for drifting into meta or topics that aren't related to the story; - "Me-too" when a comment doesn't add new information, typically a single sentence of appreciation, agreement, or humor; - "Troll" for derailing conversations into classic arguments, well-intentioned or not; - "Unkind" when uncharitable, insulting, or dismissive; - and - "Spam" for promoting commercial services. -
-- Less than 1% of stories or comments get flagged, and users are not automatically punished by flags. - Users whose stories or comments are getting flagged significantly more often are strongly encouraged to talk to mods about what's not working. - (Please don't use flagging to try to push down topics or people you don't like; click "hide" on the story and move on rather than clutter up the mod dashboard with false alarms.) -
- -- All moderator actions on this site are visible to - everyone and the identities of those moderators are <%= link_to 'public', moderators_path %>. - While the individual actions of a moderator may cause debate, there should be no question about if an action happened or who is responsible. -
- -- If users are disruptive enough to warrant banning, they will be banned - absolutely, given notice of their banning, and their disabled user profile - will indicate which moderator banned them and why. - There will be no shadow banning or other secret moderation actions. -
- -- The source code to this site and - its provisioning and deployment are - made available under a 3-clause BSD license for viewing, auditing, forking, or contributing to. - The codebase is used to run a dozen or so sister sites (that we know of) and we keep a list; - please get in touch if you've launched one. -
- -- The Lobsters community is in a sweet spot that it's large enough to be worth asking questions about and small enough the answers make sense. - We have some basic stats available, - and Peter is happy to run queries against the database and Rails/MySQL/nginx logs (but not write them for you), - as long as they don't reveal personal info like IPs, browsing, and voting or create “worst-of” leaderboards celebrating most-flagged users/comments/stories. -
- -- If you dislike the content or moderation policies here, you may prefer - Y Combinator News, - r/programming, - Slashdot, - Tilde News, or - comp.*. - Or you could use our codebase to start your own site. -
- -- Mailing list mode can be enabled - per-user to receive all new stories (including their plain-text content as - fetched and extracted by Diffbot) and user - comments as e-mails, mirroring discussion threads offline. This makes it - easy and efficient to read new stories as well as keep track of new comments - on old threads or stories, just like technical mailing lists or Usenet of - yore. Each user is assigned a private mailing list address at this domain - which allows them to reply to stories or comments directly in their e-mail - client. These e-mails are then converted and submitted to the website as - comments, just as if the comment was posted through a web browser. - <%- raise "Don't just delete that error message. You didn't set up mailing list mode, right? This really isn't your about page, write one from scratch." if Rails.env.production? and Rails.application.name != 'Lobsters' -%> -
- -- Private messaging enables users to communicate privately - without having to publicly disclose an e-mail address, and users can receive - e-mail and Pushover notifications of new - private messages. -
- Responsive design enhances functionality on smaller screens - such as phones and tablets without having to use a separate URL, 3rd party - (often read-only) websites, or mobile apps. -
- Integrated search engine covers all - submitted stories and comments, including full-text caches of all submitted - story contents. Searching for a keyword will often bring up relevant stories - that don't even mention that keyword in the URL or title. -
- Story merging collects comments on a topic that would otherwise fragment across multiple stories. - This keeps the front page from being overwhelmed by a single topic and the discussion together for those interested (or so disinterested they'd prefer to hide it). - Moderators merge stories on the same topic submitted within a week. - Here's a small and large example. -
- Fuzzy-matching of submitted story URLs to avoid duplicate - submissions of similar URLs that differ only in http vs. - https, trailing slashes, useless analytics parameters, etc. When - using the story submission bookmarklet, story URLs are automatically - converted to use the page's canonical URL (if available) to present the best - URL to represent the story, as defined by the story's author or publisher. -
- User-suggested titles and tags can - be automatically applied to a story when a quorum of users agrees on a new - title (such as removing a site's name, or appending the story's year of - publication) or set of tags, without any moderator action required. - (Log) -
- Hats are a more formal process of - allowing users to post comments while "wearing such and such hat" to - give their words more authority (such as an employee speaking for the - company, or an open source developer speaking for the project). -
- Per-tag, multi-tag and site-wide RSS feeds are - available to the public and logged-in users have private RSS feeds that - filter out each user's filtered tags. -
- Official Fediverse mirror - posts all stories that have reached the front page for easy following, retooting/sharing, or archiving. -
- Tor onion/hidden - service for anonymous access to the site. -
- Stickers will be available again when someone finds a service that will print and ship 2" square vinyl stickers - with a bleed <= 1/16" (preferably full-bleed) directly to people who want them. -
- Lobsters is hosted on three VPSs at DigitalOcean: - a s-4vcpu-8gb for the web server, - a s-2vcpu-4gb for the mariadb server, and - a s-1vcpu-1gb for the IRC bot. - Our domain name is registered with CRI Domains, who donated our first year of registration. - DNS is provided by DNSimple and - we use restic for backups to b2, both of which pushcx pays for. - Lobsters is cheap to run, so we don't take donations. -
- Sponsor of the lobster emoji: - In February 2018, Lobsters held a fundraiser - to officially adopt the new lobster emoji in support of the Unicode Foundation. -
- The name "Lobste.rs" is a cute domain hack - without any deeper meaning. - <%- require 'digest/md5'; instance_variable_set("@#{controller_name}#{action_name}", Digest::MD5.hexdigest(Rails.env) == 'fd89784e59c72499525556f80289b2c7' && Digest::MD5.hexdigest(Rails.application.name) != '4e7c4ddc593da2e7a1cc8c6dc2d38eba') -%> - It has nothing to do - with - self-help guru - Jordan Peterson, whose fans started to call themselves "lobsters" - about six years after we started. -
- As a Rails app that's big enough to have real-world complexity but small enough to be easily read, - our codebase has seen a few interesting uses: -
-Please do reach out if you find a use for our code!
-- We have a backup domain lobsters.dev in case of issues with our primary domain. -
- If you prefer the article links or comment links to open a new tab instead of navigating in your current tab you can add - a client-side script to do so. - (Discussion) -
this is a link aggregator for the tildeverse.
+- An official real-time discussion channel is available to members and guests - of the site, hosted on the - Libera.Chat IRC network - in #lobsters. - This channel was originally - created by - @kristof on freenode, and - stayed with the network on 2021-05-19 after that domain was lost. - @pushcx, - @355e3b (c355e3b on IRC), and - @aleph (Church on IRC) are channel operators. -
+- To participate in the discussion, join the - #lobsters channel on - irc.libera.chat with an IRC client. -
- -- The policies and ideals of the discussion channel are the same as the website; quality content and conversing, respect for other users, and no spamming. - Slightly off-topic discussion is generally acceptable, but we're still not open to discussion of electoral politics and policies. - The channel isn't busy enough that there's always someone talking, so don't be surprised if you try to start a conversation and no one responds. - Leave it open and you'll see activity, though we're most active during US work hours. -
- -- If you want an invite to the site, it's best to hang out and chat until people get to know you. - They'll likely ask you for a link to your homepage or a public profile to feel confident that you're not a spammer. - If you ask for an invite immediately on joining, expect people will be a lot more skeptical. -
- -- If you are the author of or otherwise involved with a story that was submitted to the site, ask and someone can send you an invite. - We've unfortunately had problems with impersonation, so it helps a lot if you point out how your email address is linked to the story. -
- -- The channel has a bot named - mockturtle. - It announces new stories submitted to the site and provides other useful features like showing the page title of URLs mentioned in the channel. -
- -- If you'd like a cloak to note that you've contributed to - Lobsters development - or just for privacy as a regular user, contact a channel operator for a - lobsters/developer/username or lobsters/user/username - cloak. -
- -- For a feed of stories without discussion, mockturtle also posts new stories in #lobsters-feed. -
- -- Lobsters used to have a channel called #lobsters-boil for off-topic conversations (especially American politics) that "boiled over" from the main channel. - It was useful in the wake of some big events, but the mods didn't want to run it indefinitely. - Community members independently run ##crustaceans subject to their own policies, if you're looking for more off-topic discussion. -
- -new posts are mirrored to tilde.chat in #meta and #tildeverse
+comments are mirrored to #tildeverse