Rename groups to clubs
This commit is contained in:
@ -91,7 +91,7 @@ struct ProfileView: View {
|
||||
}
|
||||
|
||||
NavigationLink(destination: GroupsView()) {
|
||||
Text("Recommendation Groups")
|
||||
Text("Clubs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ import Views
|
||||
|
||||
do {
|
||||
try await dataService.leaveGroup(groupID: recommendationGroup.id)
|
||||
Snackbar.show(message: "You have left the group.")
|
||||
Snackbar.show(message: "You have left the club.")
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
@ -129,9 +129,9 @@ struct RecommendationGroupView: View {
|
||||
Section("Members") {
|
||||
if !viewModel.recommendationGroup.canSeeMembers {
|
||||
Text("""
|
||||
The admin of this group does not allow viewing all members.
|
||||
The admin of this club does not allow viewing all members.
|
||||
|
||||
[Learn more about groups](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
[Learn more about clubs](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
""")
|
||||
.accentColor(.blue)
|
||||
} else if viewModel.nonAdmins.count > 0 {
|
||||
@ -144,10 +144,10 @@ struct RecommendationGroupView: View {
|
||||
}
|
||||
} else {
|
||||
Text("""
|
||||
This group does not have any members. Add users to your group by sending
|
||||
This club does not have any members. Add users to your club by sending
|
||||
them the invite link.
|
||||
|
||||
[Learn more about groups](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
[Learn more about clubs](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
""")
|
||||
.accentColor(.blue)
|
||||
}
|
||||
@ -160,7 +160,7 @@ struct RecommendationGroupView: View {
|
||||
}
|
||||
return AnyView(Button(action: {
|
||||
viewModel.showLeaveGroup = true
|
||||
}, label: { Text("Leave Group") })
|
||||
}, label: { Text("Leave Club") })
|
||||
.accentColor(.red))
|
||||
}
|
||||
|
||||
@ -196,8 +196,8 @@ struct RecommendationGroupView: View {
|
||||
}
|
||||
.alert(isPresented: $viewModel.showLeaveGroup) {
|
||||
Alert(
|
||||
title: Text("Are you sure you want to leave this group? No data will be deleted, but you will stop receiving recommendations from the group."),
|
||||
primaryButton: .destructive(Text("Leave Group")) {
|
||||
title: Text("Are you sure you want to leave this club? No data will be deleted, but you will stop receiving recommendations from the club."),
|
||||
primaryButton: .destructive(Text("Leave Club")) {
|
||||
Task {
|
||||
let success = await viewModel.leaveGroup(dataService: dataService)
|
||||
if success {
|
||||
|
||||
@ -40,7 +40,7 @@ import Views
|
||||
await loadGroups(dataService: dataService)
|
||||
showCreateSheet = false
|
||||
} else {
|
||||
createGroupError = "Error creating group"
|
||||
createGroupError = "Error creating club"
|
||||
showCreateError = true
|
||||
}
|
||||
|
||||
@ -72,9 +72,9 @@ struct CreateRecommendationGroupView: View {
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
Form {
|
||||
TextField("Name", text: $name, prompt: Text("Group Name"))
|
||||
TextField("Name", text: $name, prompt: Text("Club Name"))
|
||||
|
||||
Section {
|
||||
Section("Club Rules") {
|
||||
Toggle("Only admins can post", isOn: $viewModel.onlyAdminCanPost)
|
||||
Toggle("Only admins can see members", isOn: $viewModel.onlyAdminCanSeeMembers)
|
||||
}
|
||||
@ -82,7 +82,7 @@ struct CreateRecommendationGroupView: View {
|
||||
Section {
|
||||
Section {
|
||||
Text("""
|
||||
[Learn more about groups](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
[Learn more about clubs](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
""")
|
||||
.accentColor(.blue)
|
||||
}
|
||||
@ -99,7 +99,7 @@ struct CreateRecommendationGroupView: View {
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
.navigationTitle("Create Group")
|
||||
.navigationTitle("Create Club")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarItems(leading:
|
||||
Button(action: {
|
||||
@ -132,7 +132,7 @@ struct GroupsView: View {
|
||||
}
|
||||
}
|
||||
.task { await viewModel.loadGroups(dataService: dataService) }
|
||||
.navigationTitle("Recommendation Groups")
|
||||
.navigationTitle("Clubs")
|
||||
}
|
||||
|
||||
private var innerBody: some View {
|
||||
@ -143,7 +143,7 @@ struct GroupsView: View {
|
||||
label: {
|
||||
HStack {
|
||||
Image(systemName: "plus.circle.fill").foregroundColor(.green)
|
||||
Text("Create a new group")
|
||||
Text("Create a new club")
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ struct GroupsView: View {
|
||||
|
||||
if !viewModel.isLoading {
|
||||
if viewModel.recommendationGroups.count > 0 {
|
||||
Section(header: Text("Your recommendation groups")) {
|
||||
Section(header: Text("Your clubs")) {
|
||||
ForEach(viewModel.recommendationGroups) { recommendationGroup in
|
||||
let vm = RecommendationsGroupViewModel(recommendationGroup: recommendationGroup)
|
||||
NavigationLink(
|
||||
@ -165,13 +165,13 @@ struct GroupsView: View {
|
||||
} else {
|
||||
Section {
|
||||
Text("""
|
||||
You are not a member of any groups.
|
||||
Create a new group and send the invite link to your friends get started.
|
||||
You are not a member of any clubs.
|
||||
Create a new club and send the invite link to your friends get started.
|
||||
|
||||
During the beta you are limited to creating three groups, and each group
|
||||
During the beta you are limited to creating three clubs, and each club
|
||||
can have a maximum of twelve users.
|
||||
|
||||
[Learn more about groups](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
[Learn more about clubs](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
""")
|
||||
.accentColor(.blue)
|
||||
}
|
||||
|
||||
@ -29,9 +29,9 @@ import Views
|
||||
do {
|
||||
dataService.viewContext.performAndWait {
|
||||
let fetchRequest: NSFetchRequest<Models.RecommendationGroup> = RecommendationGroup.fetchRequest()
|
||||
let sort = NSSortDescriptor(key: #keyPath(RecommendationGroup.createdAt), ascending: false)
|
||||
fetchRequest.sortDescriptors = [sort]
|
||||
let sort = NSSortDescriptor(key: #keyPath(RecommendationGroup.name), ascending: true)
|
||||
fetchRequest.predicate = NSPredicate(format: "canPost == %@", NSNumber(value: true))
|
||||
fetchRequest.sortDescriptors = [sort]
|
||||
|
||||
// If this fails we will fallback to making the API call
|
||||
let groups = try? dataService.viewContext.fetch(fetchRequest).compactMap { object in
|
||||
@ -41,7 +41,10 @@ import Views
|
||||
self.recommendationGroups = groups
|
||||
}
|
||||
}
|
||||
recommendationGroups = try await dataService.recommendationGroups().filter(\.canPost)
|
||||
recommendationGroups = try await dataService.recommendationGroups()
|
||||
.filter(\.canPost)
|
||||
.sorted(by: { $0.name < $1.name })
|
||||
|
||||
} catch {
|
||||
print("ERROR fetching recommendationGroups: ", error)
|
||||
networkError = true
|
||||
@ -160,15 +163,15 @@ struct RecommendToView: View {
|
||||
List {
|
||||
if !viewModel.isLoading, viewModel.recommendationGroups.count < 1 {
|
||||
Text("""
|
||||
You do not have any groups you can post to.
|
||||
You do not have any clubs you can post to.
|
||||
|
||||
Join a group or create your own to start recommending articles.
|
||||
Join a club or create your own to start recommending articles.
|
||||
|
||||
[Learn more about groups](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
[Learn more about clubs](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
""")
|
||||
.accentColor(.blue)
|
||||
} else {
|
||||
Section("Select groups to recommend to") {
|
||||
Section("Select clubs to recommend to") {
|
||||
ForEach(viewModel.recommendationGroups) { group in
|
||||
HStack {
|
||||
Text(group.name)
|
||||
|
||||
@ -53,15 +53,15 @@ public struct FeaturePrimer: View {
|
||||
public static var recommendationsPrimer: some View {
|
||||
FeaturePrimer(
|
||||
isBeta: true,
|
||||
title: "Introducing Recommendation Groups",
|
||||
title: "Introducing Clubs",
|
||||
message: """
|
||||
Recommendation groups make it easy to share great reads with friends and co-workers.
|
||||
Clubs make it easy to share great reads with friends and co-workers.
|
||||
|
||||
To get started, create a Recommendation Group from the profile page and invite some friends.
|
||||
To get started, create a club from the profile page and invite some friends.
|
||||
|
||||
*During the beta you can create a max of three groups. Group sizes are limited to 12 people.*
|
||||
*During the beta you can create a max of three clubs. Club sizes are limited to 12 people.*
|
||||
|
||||
[Learn more about groups](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
[Learn more about clubs](https://blog.omnivore.app/p/dca38ba4-8a74-42cc-90ca-d5ffa5d075cc)
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
@ -8,25 +8,25 @@ import {
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
} from 'typeorm';
|
||||
import AdminJs from 'adminjs';
|
||||
import { Database, Resource } from '@adminjs/typeorm';
|
||||
} from 'typeorm'
|
||||
import AdminJs from 'adminjs'
|
||||
import { Database, Resource } from '@adminjs/typeorm'
|
||||
|
||||
export const registerDatabase = async (): Promise<Connection> => {
|
||||
AdminJs.registerAdapter({ Database, Resource });
|
||||
AdminJs.registerAdapter({ Database, Resource })
|
||||
|
||||
let host = 'localhost';
|
||||
let host = 'localhost'
|
||||
if (process.env.K_SERVICE) {
|
||||
console.log(
|
||||
'connecting to database via Cloud Run connection',
|
||||
process.env.CLOUD_SQL_CONNECTION_NAME,
|
||||
process.env.DB_NAME,
|
||||
);
|
||||
const dbSocketPath = process.env.DB_SOCKET_PATH || '/cloudsql';
|
||||
host = `${dbSocketPath}/${process.env.CLOUD_SQL_CONNECTION_NAME}`;
|
||||
process.env.DB_NAME
|
||||
)
|
||||
const dbSocketPath = process.env.DB_SOCKET_PATH || '/cloudsql'
|
||||
host = `${dbSocketPath}/${process.env.CLOUD_SQL_CONNECTION_NAME}`
|
||||
}
|
||||
|
||||
console.log('connecting to database:', host);
|
||||
console.log('connecting to database:', host)
|
||||
const connection = await createConnection({
|
||||
type: 'postgres',
|
||||
host: host,
|
||||
@ -35,81 +35,78 @@ export const registerDatabase = async (): Promise<Connection> => {
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_DATABASE,
|
||||
entities: [AdminUser, User, UserProfile, UserArticle],
|
||||
});
|
||||
})
|
||||
|
||||
return connection;
|
||||
};
|
||||
return connection
|
||||
}
|
||||
|
||||
@Entity({ name: 'admin_user' })
|
||||
export class AdminUser extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
public id!: string;
|
||||
public id!: string
|
||||
|
||||
@Column({ type: 'text' })
|
||||
public email!: string;
|
||||
public email!: string
|
||||
|
||||
@Column({ type: 'text' })
|
||||
public password!: string;
|
||||
public password!: string
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class User extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
id!: string
|
||||
|
||||
@Column('text')
|
||||
name!: string
|
||||
|
||||
@Column({ type: 'text' })
|
||||
public first_name!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
public last_name!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
public email!: string;
|
||||
public email!: string
|
||||
|
||||
@Column({ type: 'timestamp' })
|
||||
public created_at!: Date;
|
||||
public created_at!: Date
|
||||
|
||||
@Column({ type: 'timestamp' })
|
||||
public updated_at!: Date;
|
||||
public updated_at!: Date
|
||||
|
||||
@OneToMany(() => UserArticle, ua => ua.user)
|
||||
articles!: UserArticle[];
|
||||
@OneToMany(() => UserArticle, (ua) => ua.user)
|
||||
articles!: UserArticle[]
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class UserProfile extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
id!: string
|
||||
|
||||
@Column({ type: 'text' })
|
||||
public username!: string;
|
||||
public username!: string
|
||||
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
@ManyToOne(() => User, user => user.articles, { eager: true })
|
||||
user!: User;
|
||||
@ManyToOne(() => User, (user) => user.articles, { eager: true })
|
||||
user!: User
|
||||
}
|
||||
|
||||
@Entity({ name: 'user_articles' })
|
||||
export class UserArticle extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
id!: string
|
||||
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
@ManyToOne(() => User, user => user.articles, { eager: true })
|
||||
user!: User;
|
||||
@ManyToOne(() => User, (user) => user.articles, { eager: true })
|
||||
user!: User
|
||||
|
||||
@Column({ type: 'text', name: 'article_id' })
|
||||
articleId!: string;
|
||||
articleId!: string
|
||||
|
||||
@Column({ type: 'text' })
|
||||
slug!: string;
|
||||
slug!: string
|
||||
|
||||
@Column({ type: 'timestamp', name: 'created_at' })
|
||||
createdAt!: Date;
|
||||
createdAt!: Date
|
||||
|
||||
@Column({ type: 'timestamp', name: 'updated_at' })
|
||||
updatedAt!: Date;
|
||||
updatedAt!: Date
|
||||
|
||||
@Column({ type: 'timestamp', name: 'saved_at' })
|
||||
savedAt!: Date;
|
||||
savedAt!: Date
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user