diff --git a/cmd/server/main-server.go b/cmd/server/main-server.go index b608927a0e..4e682edb95 100644 --- a/cmd/server/main-server.go +++ b/cmd/server/main-server.go @@ -199,7 +199,7 @@ func beforeSendActivityUpdate(ctx context.Context) { } } -func startupActivityUpdate() { +func startupActivityUpdate(firstLaunch bool) { ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second) defer cancelFn() activity := wshrpc.ActivityUpdate{Startup: 1} @@ -209,7 +209,7 @@ func startupActivityUpdate() { } autoUpdateChannel := telemetry.AutoUpdateChannel() autoUpdateEnabled := telemetry.IsAutoUpdateEnabled() - tevent := telemetrydata.MakeTEvent("app:startup", telemetrydata.TEventProps{ + props := telemetrydata.TEventProps{ UserSet: &telemetrydata.TEventUserProps{ ClientVersion: "v" + WaveVersion, ClientBuildTime: BuildTime, @@ -222,7 +222,11 @@ func startupActivityUpdate() { UserSetOnce: &telemetrydata.TEventUserProps{ ClientInitialVersion: "v" + WaveVersion, }, - }) + } + if firstLaunch { + props.AppFirstLaunch = true + } + tevent := telemetrydata.MakeTEvent("app:startup", props) err = telemetry.RecordTEvent(ctx, tevent) if err != nil { log.Printf("error recording startup event: %v\n", err) @@ -367,11 +371,14 @@ func main() { log.Printf("error initializing wsh and shell-integration files: %v\n", err) } }() - err = wcore.EnsureInitialData() + firstLaunch, err := wcore.EnsureInitialData() if err != nil { log.Printf("error ensuring initial data: %v\n", err) return } + if firstLaunch { + log.Printf("first launch detected") + } err = clearTempFiles() if err != nil { log.Printf("error clearing temp files: %v\n", err) @@ -385,7 +392,7 @@ func main() { go stdinReadWatch() go telemetryLoop() go updateTelemetryCountsLoop() - startupActivityUpdate() // must be after startConfigWatcher() + startupActivityUpdate(firstLaunch) // must be after startConfigWatcher() blocklogger.InitBlockLogger() webListener, err := web.MakeTCPListener("web") diff --git a/pkg/telemetry/telemetrydata/telemetrydata.go b/pkg/telemetry/telemetrydata/telemetrydata.go index a390e2bc0a..52b163f0d8 100644 --- a/pkg/telemetry/telemetrydata/telemetrydata.go +++ b/pkg/telemetry/telemetrydata/telemetrydata.go @@ -70,7 +70,8 @@ type TEventProps struct { FgMinutes int `json:"activity:fgminutes,omitempty"` OpenMinutes int `json:"activity:openminutes,omitempty"` - AppFirstDay bool `json:"app:firstday,omitempty"` + AppFirstDay bool `json:"app:firstday,omitempty"` + AppFirstLaunch bool `json:"app:firstlaunch,omitempty"` ActionInitiator string `json:"action:initiator,omitempty" tstype:"\"keyboard\" | \"mouse\""` PanicType string `json:"debug:panictype,omitempty"` diff --git a/pkg/wcore/wcore.go b/pkg/wcore/wcore.go index c21c892dff..fb2281e26f 100644 --- a/pkg/wcore/wcore.go +++ b/pkg/wcore/wcore.go @@ -20,7 +20,7 @@ import ( // orchestrating the wave object store, the wave pubsub system, and the wave rpc system // Ensures that the initial data is present in the store, creates an initial window if needed -func EnsureInitialData() error { +func EnsureInitialData() (bool, error) { // does not need to run in a transaction since it is called on startup ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second) defer cancelFn() @@ -29,11 +29,7 @@ func EnsureInitialData() error { if err == wstore.ErrNotFound { client, err = CreateClient(ctx) if err != nil { - return fmt.Errorf("error creating client: %w", err) - } - migrateErr := wstore.TryMigrateOldHistory() - if migrateErr != nil { - log.Printf("error migrating old history: %v\n", migrateErr) + return false, fmt.Errorf("error creating client: %w", err) } firstLaunch = true } @@ -42,33 +38,33 @@ func EnsureInitialData() error { client.TempOID = uuid.NewString() err = wstore.DBUpdate(ctx, client) if err != nil { - return fmt.Errorf("error updating client: %w", err) + return firstLaunch, fmt.Errorf("error updating client: %w", err) } } log.Printf("clientid: %s\n", client.OID) if len(client.WindowIds) == 1 { log.Println("client has one window") CheckAndFixWindow(ctx, client.WindowIds[0]) - return nil + return firstLaunch, nil } if len(client.WindowIds) > 0 { log.Println("client has windows") - return nil + return firstLaunch, nil } wsId := "" if firstLaunch { log.Println("client has no windows and first launch, creating starter workspace") starterWs, err := CreateWorkspace(ctx, "Starter workspace", "custom@wave-logo-solid", "#58C142", false, true) if err != nil { - return fmt.Errorf("error creating starter workspace: %w", err) + return firstLaunch, fmt.Errorf("error creating starter workspace: %w", err) } wsId = starterWs.OID } _, err = CreateWindow(ctx, nil, wsId) if err != nil { - return fmt.Errorf("error creating window: %w", err) + return firstLaunch, fmt.Errorf("error creating window: %w", err) } - return nil + return firstLaunch, nil } func CreateClient(ctx context.Context) (*waveobj.Client, error) {