Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
/config/multisite.yml
# `discourse_dev` gem
/config/dev.yml

/config/database.yml
/config/discourse_defaults.conf
/public/assets
/public/backups
/public/csv
Expand Down Expand Up @@ -121,3 +122,7 @@ openapi/*

# direnv.net
.direnv

.idea

.cursor/*
76 changes: 76 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# 使用 Ubuntu 作为基础镜像
FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive \
RUBY_VERSION=3.3.0 \
BUNDLER_VERSION=2.6.4 \
LANG=C.UTF-8

# 安装系统依赖
RUN apt-get update && apt-get install -y \
bash \
curl \
git \
build-essential \
libssl-dev \
libreadline-dev \
zlib1g-dev \
libyaml-dev \
libffi-dev \
libgdbm-dev \
libncurses5-dev \
libdb-dev \
ca-certificates \
autoconf \
bison \
libxml2-dev \
libxslt1-dev \
tzdata \
imagemagick \
gnupg2 \
&& rm -rf /var/lib/apt/lists/*

# 安装 Node.js 20(兼容 pnpm 10+)
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs && \
node -v && npm -v

# 安装 pnpm
RUN npm install -g pnpm && pnpm -v

# 安装 ruby-build 用于编译 Ruby
RUN git clone https://github.com/rbenv/ruby-build.git /tmp/ruby-build && \
/tmp/ruby-build/install.sh && \
rm -rf /tmp/ruby-build

# 编译安装 Ruby 3.3
RUN ruby-build "$RUBY_VERSION" /usr/local

# 设置 Ruby 可执行路径
RUN ln -sf /usr/local/bin/ruby /usr/bin/ruby && \
ln -sf /usr/local/bin/gem /usr/bin/gem

# 安装 Bundler
RUN gem install bundler -v ${BUNDLER_VERSION} && \
bundler -v

# 创建应用目录
WORKDIR /app

# 拷贝 Gemfile 和 Gemfile.lock
COPY Gemfile Gemfile.lock ./
RUN gem install bundler -v 2.4.22
RUN bundle config set without 'development test'
RUN bundle install

# 拷贝项目代码
COPY . .

# 编译 assets(可选)
RUN RAILS_ENV=production bundle exec rake assets:precompile

# 暴露端口
EXPOSE 3000

# 启动 puma
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,17 @@ For over a decade, our [amazing community](https://meta.discourse.org/) has help

We’re deeply grateful for every feature request, bug report, and discussion that has driven Discourse forward. Thank you for being a part of this journey—we couldn’t have done it without you!

# 创建新用户
user = User.new(
username: "monalee2",
email: "limeng_lm5@yeah.net",
password: "123limengLM20250806",
active: true,
approved: true
)
user.skip_email_validation = true
user.save!(validate: false) # 跳过所有 ActiveRecord 验证


email = "limeng_lm3@yeah.net"
username = "monalee"
2 changes: 1 addition & 1 deletion app/assets/javascripts/discourse-widget-hbs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@glimmer/component": "^1.1.2",
"@glimmer/syntax": "0.93.1",
"broccoli-asset-rev": "^3.0.0",
"ember-cli": "~6.5.0",
"ember-cli": "~6.6.0",
"ember-cli-inject-live-reload": "^2.1.0",
"ember-cli-sri": "^2.1.1",
"ember-cli-terser": "^4.0.2",
Expand Down
204 changes: 63 additions & 141 deletions app/assets/javascripts/discourse/app/components/topic-list/item.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export default class Item extends Component {
}

<template>
<tr
<div
{{! template-lint-disable no-invalid-interactive }}
{{this.highlightIfNeeded}}
{{on "keydown" this.keyDown}}
Expand Down Expand Up @@ -279,157 +279,79 @@ export default class Item extends Component {
navigateToTopic=this.navigateToTopic
}}
>
{{#if this.useMobileLayout}}
<td
class={{concatClass
"topic-list-data"
(if @bulkSelectEnabled "bulk-select-enabled")
}}
>
<div class="pull-left">
{{#if @bulkSelectEnabled}}
<label for="bulk-select-{{@topic.id}}">
<input
{{on "click" this.onBulkSelectToggle}}
checked={{this.isSelected}}
type="checkbox"
id="bulk-select-{{@topic.id}}"
class="bulk-select"
/>
</label>
{{else}}
<PluginOutlet
@name="topic-list-item-mobile-avatar"
@outletArgs={{lazyHash topic=@topic}}
>
<UserLink
@ariaLabel={{i18n
"latest_poster_link"
username=@topic.lastPosterUser.username
}}
@username={{@topic.lastPosterUser.username}}
>
{{avatar
@topic.lastPosterUser
imageSize="large"
}}</UserLink>
</PluginOutlet>
{{/if}}
</div>

<div class="topic-item-metadata right">
{{~! no whitespace ~}}
<PluginOutlet
@name="topic-list-before-link"
@outletArgs={{lazyHash topic=@topic}}
/>

<div class="main-link">
{{~! no whitespace ~}}
<PluginOutlet
@name="topic-list-before-status"
@outletArgs={{lazyHash topic=@topic}}
/>
{{~! no whitespace ~}}
<TopicStatus @topic={{@topic}} @context="topic-list" />
{{~! no whitespace ~}}
<TopicLink
{{on "focus" this.onTitleFocus}}
{{on "blur" this.onTitleBlur}}
@topic={{@topic}}
class="raw-link raw-topic-link"
/>
{{~#if @topic.featured_link~}}
&nbsp;
{{~topicFeaturedLink @topic}}
{{~/if~}}
<PluginOutlet
@name="topic-list-after-title"
@outletArgs={{lazyHash topic=@topic}}
/>
{{~#if @topic.unseen~}}
<span class="topic-post-badges">&nbsp;<span
class="badge-notification new-topic"
></span></span>
{{~/if~}}
<PluginOutlet
@name="topic-list-after-badges"
@outletArgs={{lazyHash topic=@topic}}
/>
{{~#if this.expandPinned~}}
<TopicExcerpt @topic={{@topic}} />
{{~/if~}}
<PluginOutlet
@name="topic-list-main-link-bottom"
@outletArgs={{lazyHash
topic=@topic
expandPinned=this.expandPinned
}}
<div class="topic-card-content">
{{#if @bulkSelectEnabled}}
<div class="topic-card-bulk-select">
<label for="bulk-select-{{@topic.id}}">
<input
{{on "click" this.onBulkSelectToggle}}
checked={{this.isSelected}}
type="checkbox"
id="bulk-select-{{@topic.id}}"
class="bulk-select"
/>
</label>
</div>
{{/if}}

<div class="topic-card-image">
{{#if @topic.image_url}}
<img src={{@topic.image_url}} alt="Topic image" />
{{else}}
<div class="topic-card-image-placeholder">
<span class="d-icon d-icon-image"></span>
</div>
{{~! no whitespace ~}}
{{/if}}
</div>

<div class="topic-card-body">
<div class="topic-card-title">
<TopicLink
{{on "focus" this.onTitleFocus}}
{{on "blur" this.onTitleBlur}}
@topic={{@topic}}
class="raw-link raw-topic-link"
/>
<PluginOutlet
@name="topic-list-after-main-link"
@name="topic-list-after-title"
@outletArgs={{lazyHash topic=@topic}}
/>
</div>

<div class="pull-right">
<PostCountOrBadges
@topic={{@topic}}
@postBadgesEnabled={{@showTopicPostBadges}}
/>
<div class="topic-card-description">
{{#if @topic.excerpt}}
{{@topic.excerpt}}
{{else}}
{{@topic.fancy_title}}
{{/if}}
</div>

<div class="topic-card-footer">
<div class="topic-card-user">
<UserLink @username={{@topic.lastPosterUser.username}}>
{{avatar @topic.lastPosterUser imageSize="small"}}
</UserLink>
<span class="topic-card-username">{{@topic.lastPosterUser.username}}</span>
</div>

<div class="topic-item-stats clearfix">
<span class="topic-item-stats__category-tags">
{{#unless @hideCategory}}
<PluginOutlet
@name="topic-list-before-category"
@outletArgs={{lazyHash topic=@topic}}
/>
{{categoryLink @topic.category}}
{{~! no whitespace ~}}
<PluginOutlet
@name="topic-list-after-category"
@outletArgs={{lazyHash topic=@topic}}
/>{{~! no whitespace ~}}
{{/unless}}
{{~! no whitespace ~}}
{{discourseTags @topic mode="list"}}
<div class="topic-card-stats">
<span class="topic-stat">
<span class="d-icon d-icon-eye"></span>
<span class="stat-number">{{@topic.views}}</span>
</span>
<span class="topic-stat">
<span class="d-icon d-icon-thumbtack"></span>
<span class="stat-number">{{@topic.like_count}}</span>
</span>
<span class="topic-stat">
<span class="d-icon d-icon-reply"></span>
<span class="stat-number">{{@topic.reply_count}}</span>
</span>

<div class="num activity last">
<PluginOutlet
@name="topic-list-item-mobile-bumped-at"
@outletArgs={{lazyHash topic=@topic}}
>
<span title={{@topic.bumpedAtTitle}} class="age activity">
<a href={{@topic.lastPostUrl}}>{{formatDate
@topic.bumpedAt
format="tiny"
noTitle="true"
}}</a>
</span>
</PluginOutlet>
</div>
</div>
</div>
</td>
{{else}}
{{#each @columns as |entry|}}
<entry.value.item
@topic={{@topic}}
@bulkSelectEnabled={{@bulkSelectEnabled}}
@onBulkSelectToggle={{this.onBulkSelectToggle}}
@isSelected={{this.isSelected}}
@showTopicPostBadges={{@showTopicPostBadges}}
@hideCategory={{@hideCategory}}
@tagsForUser={{@tagsForUser}}
@expandPinned={{this.expandPinned}}
/>
{{/each}}
{{/if}}
</div>
</div>
</PluginOutlet>
</tr>
</div>
</template>
}
Loading