feat: add resource visibility to user setting (#1190)

This commit is contained in:
boojack 2023-02-27 22:16:33 +08:00 committed by GitHub
parent ae61ade2b1
commit 9577f6dbe8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 17 deletions

View File

@ -16,6 +16,8 @@ const (
UserSettingAppearanceKey UserSettingKey = "appearance"
// UserSettingMemoVisibilityKey is the key type for user preference memo default visibility.
UserSettingMemoVisibilityKey UserSettingKey = "memoVisibility"
// UserSettingResourceVisibilityKey is the key type for user preference resource default visibility.
UserSettingResourceVisibilityKey UserSettingKey = "resourceVisibility"
)
// String returns the string format of UserSettingKey type.
@ -27,14 +29,17 @@ func (key UserSettingKey) String() string {
return "appearance"
case UserSettingMemoVisibilityKey:
return "memoVisibility"
case UserSettingResourceVisibilityKey:
return "resourceVisibility"
}
return ""
}
var (
UserSettingLocaleValue = []string{"en", "zh", "vi", "fr", "nl", "sv", "de", "es", "uk", "ru", "it", "hant", "ko"}
UserSettingAppearanceValue = []string{"system", "light", "dark"}
UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public}
UserSettingLocaleValue = []string{"en", "zh", "vi", "fr", "nl", "sv", "de", "es", "uk", "ru", "it", "hant", "ko"}
UserSettingAppearanceValue = []string{"system", "light", "dark"}
UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public}
UserSettingResourceVisibilityValue = []Visibility{Private, Protected, Public}
)
type UserSetting struct {
@ -78,6 +83,15 @@ func (upsert UserSettingUpsert) Validate() error {
if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) {
return fmt.Errorf("invalid user setting memo visibility value")
}
} else if upsert.Key == UserSettingResourceVisibilityKey {
resourceVisibilityValue := Private
err := json.Unmarshal([]byte(upsert.Value), &resourceVisibilityValue)
if err != nil {
return fmt.Errorf("failed to unmarshal user setting resource visibility value")
}
if !slices.Contains(UserSettingResourceVisibilityValue, resourceVisibilityValue) {
return fmt.Errorf("invalid user setting resource visibility value")
}
} else {
return fmt.Errorf("invalid user setting key")
}
@ -88,7 +102,7 @@ func (upsert UserSettingUpsert) Validate() error {
type UserSettingFind struct {
UserID int
Key *UserSettingKey `json:"key"`
Key UserSettingKey `json:"key"`
}
type UserSettingDelete struct {

View File

@ -30,10 +30,9 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
}
if memoCreate.Visibility == "" {
userSettingMemoVisibilityKey := api.UserSettingMemoVisibilityKey
userMemoVisibilitySetting, err := s.Store.FindUserSetting(ctx, &api.UserSettingFind{
UserID: userID,
Key: &userSettingMemoVisibilityKey,
Key: api.UserSettingMemoVisibilityKey,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user setting").SetInternal(err)

View File

@ -42,7 +42,28 @@ func (s *Server) registerResourceRoutes(g *echo.Group) {
if resourceCreate.ExternalLink != "" && !strings.HasPrefix(resourceCreate.ExternalLink, "http") {
return echo.NewHTTPError(http.StatusBadRequest, "Invalid external link")
}
resourceCreate.Visibility = api.Private
if resourceCreate.Visibility == "" {
userResourceVisibilitySetting, err := s.Store.FindUserSetting(ctx, &api.UserSettingFind{
UserID: userID,
Key: api.UserSettingResourceVisibilityKey,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user setting").SetInternal(err)
}
if userResourceVisibilitySetting != nil {
resourceVisibility := api.Private
err := json.Unmarshal([]byte(userResourceVisibilitySetting.Value), &resourceVisibility)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal user setting value").SetInternal(err)
}
resourceCreate.Visibility = resourceVisibility
} else {
// Private is the default resource visibility.
resourceCreate.Visibility = api.Private
}
}
resource, err := s.Store.CreateResource(ctx, resourceCreate)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create resource").SetInternal(err)
@ -100,12 +121,11 @@ func (s *Server) registerResourceRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to read file").SetInternal(err)
}
resourceCreate = &api.ResourceCreate{
CreatorID: userID,
Filename: filename,
Type: filetype,
Size: size,
Blob: fileBytes,
Visibility: api.Private,
CreatorID: userID,
Filename: filename,
Type: filetype,
Size: size,
Blob: fileBytes,
}
} else {
storage, err := s.Store.FindStorage(ctx, &api.StorageFind{ID: &storageServiceID})
@ -136,13 +156,34 @@ func (s *Server) registerResourceRoutes(g *echo.Group) {
Filename: filename,
Type: filetype,
ExternalLink: link,
Visibility: api.Private,
}
} else {
return echo.NewHTTPError(http.StatusInternalServerError, "Unsupported storage type")
}
}
if resourceCreate.Visibility == "" {
userResourceVisibilitySetting, err := s.Store.FindUserSetting(ctx, &api.UserSettingFind{
UserID: userID,
Key: api.UserSettingResourceVisibilityKey,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user setting").SetInternal(err)
}
if userResourceVisibilitySetting != nil {
resourceVisibility := api.Private
err := json.Unmarshal([]byte(userResourceVisibilitySetting.Value), &resourceVisibility)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal user setting value").SetInternal(err)
}
resourceCreate.Visibility = resourceVisibility
} else {
// Private is the default resource visibility.
resourceCreate.Visibility = api.Private
}
}
resource, err := s.Store.CreateResource(ctx, resourceCreate)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create resource").SetInternal(err)

View File

@ -120,8 +120,8 @@ func upsertUserSetting(ctx context.Context, tx *sql.Tx, upsert *api.UserSettingU
func findUserSettingList(ctx context.Context, tx *sql.Tx, find *api.UserSettingFind) ([]*userSettingRaw, error) {
where, args := []string{"1 = 1"}, []interface{}{}
if v := find.Key; v != nil {
where, args = append(where, "key = ?"), append(args, v.String())
if v := find.Key.String(); v != "" {
where, args = append(where, "key = ?"), append(args, v)
}
where, args = append(where, "user_id = ?"), append(args, find.UserID)

View File

@ -34,6 +34,10 @@ const PreferencesSection = () => {
await userStore.upsertUserSetting("memoVisibility", value);
};
const handleDefaultResourceVisibilityChanged = async (value: string) => {
await userStore.upsertUserSetting("resourceVisibility", value);
};
const handleIsFoldingEnabledChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
userStore.upsertLocalSetting({ ...localSetting, enableFoldMemo: event.target.checked });
};
@ -72,6 +76,24 @@ const PreferencesSection = () => {
))}
</Select>
</div>
<div className="form-label selector">
<span className="normal-text">Default resource visibility</span>
<Select
className="!min-w-[10rem] w-auto text-sm"
value={setting.resourceVisibility}
onChange={(_, visibility) => {
if (visibility) {
handleDefaultResourceVisibilityChanged(visibility);
}
}}
>
{visibilitySelectorItems.map((item) => (
<Option key={item.value} value={item.value} className="whitespace-nowrap">
{item.text}
</Option>
))}
</Select>
</div>
<label className="form-label selector">
<span className="normal-text">{t("setting.preference-section.enable-folding-memo")}</span>
<Switch className="ml-2" checked={localSetting.enableFoldMemo} onChange={handleIsFoldingEnabledChanged} />

View File

@ -10,6 +10,7 @@ const defaultSetting: Setting = {
locale: "en",
appearance: getSystemColorScheme(),
memoVisibility: "PRIVATE",
resourceVisibility: "PRIVATE",
};
const defaultLocalSetting: LocalSetting = {

View File

@ -4,6 +4,7 @@ interface Setting {
locale: Locale;
appearance: Appearance;
memoVisibility: Visibility;
resourceVisibility: Visibility;
}
interface LocalSetting {
@ -26,7 +27,12 @@ interface UserMemoVisibilitySetting {
value: Visibility;
}
type UserSetting = UserLocaleSetting | UserAppearanceSetting | UserMemoVisibilitySetting;
interface UserResourceVisibilitySetting {
key: "resourceVisibility";
value: Visibility;
}
type UserSetting = UserLocaleSetting | UserAppearanceSetting | UserMemoVisibilitySetting | UserResourceVisibilitySetting;
interface UserSettingUpsert {
key: keyof Setting;